CDash¶
隨著專案的測試需求增加,追蹤測試結果可能會變得難以負荷。對於需要在許多不同平台上進行夜間測試的專案來說,尤其如此。在這些情況下,我們建議使用測試儀表板來總結測試結果。
測試儀表板總結了許多平台上的多項測試結果,其超連結可讓人們快速深入了解更多詳細資訊。CTest 可執行檔支援產生測試儀表板。當使用正確的選項執行時,CTest 會產生 XML 格式的輸出,記錄建置和測試結果,並將其發佈到儀表板伺服器。儀表板伺服器執行一個名為 CDash 的開源軟體套件。CDash 會收集 XML 結果,並從中產生 HTML 網頁。
在討論如何使用 CTest 產生儀表板之前,讓我們先考慮測試儀表板的主要部分。每天晚上在指定的時間,儀表板伺服器將開啟一個新的儀表板,因此每天都會有一個新的網頁顯示該 24 小時期間的測試結果。主要頁面上有連結,可讓您快速瀏覽不同的日期。查看專案的主要頁面(例如,來自 www.cmake.org 的 CMake 儀表板),您會發現它分為幾個主要元件。在頂部附近,您會找到一組連結,可讓您跳到先前的儀表板,以及專案頁面的連結,例如錯誤追蹤器、文件等。
在下方,您會找到結果群組。通常,您會找到的群組包括「夜間」、「實驗性」、「持續」、「涵蓋率」和「動態分析」。儀表板條目將歸類於哪個類別取決於它的產生方式。最簡單的是「實驗性」條目,它代表某人目前專案原始碼副本的儀表板結果。使用實驗性儀表板時,無法保證原始碼是最新的。相反地,「夜間」儀表板條目是指 CTest 嘗試將原始碼更新至特定日期和時間的條目。預期指定日期的所有夜間儀表板條目都應基於相同的原始碼。
「持續」儀表板條目是指設計為每次簽入新檔案時執行的條目。根據簽入新檔案的頻率,單日的儀表板可能會有許多持續條目。「持續」儀表板對於跨平台專案特別有用,因為問題可能只會出現在某些平台上。在這些情況下,開發人員可以提交一個在其平台上適用的變更,然後另一個執行持續建置的平台可以捕捉到錯誤,讓開發人員立即更正問題。
「動態分析」和「涵蓋率」儀表板旨在測試專案的記憶體安全性和程式碼涵蓋率。「動態分析」儀表板條目是指所有測試都在啟用記憶體存取/洩漏檢查程式的情況下執行的條目。任何產生的錯誤或警告都會被解析、總結和顯示。這對於驗證您的軟體是否沒有洩漏記憶體或從未初始化的記憶體讀取至關重要。「涵蓋率」儀表板條目類似,所有測試都會執行,但在執行時會追蹤所執行的程式碼行。當所有測試都執行完畢後,會產生一個列出每行程式碼執行次數的清單,並顯示在儀表板上。
為專案新增 CDash 儀表板支援¶
開始使用 CDash 的最簡單方法是在 https://my.cdash.org 註冊帳戶並建立新專案。
如果您希望安裝自己的 CDash 伺服器,請依照下列其中一個指南
用戶端設定¶
若要支援專案中的儀表板,您需要包含 CTest
模組,如下所示。
# Include CDash dashboard testing module
include(CTest)
然後,CTest 模組會從您建立或從 CDash 下載的 CTestConfig.cmake
檔案中讀取設定。如果您已將 add_test
命令呼叫新增至您的專案,則建立儀表板條目就像執行一樣簡單
ctest -D Experimental
-D
選項會告知 CTest 建立儀表板條目。下一個引數表示要建立的儀表板條目類型。建立儀表板條目涉及相當多的步驟,這些步驟可以獨立執行,也可以作為一個命令執行。在本範例中,「實驗性」引數會導致 CTest 作為一個命令執行許多不同的步驟。以下概述了建立儀表板條目的不同步驟。
- 開始
準備新的儀表板條目。這會在建置目錄中建立
Testing
子目錄。Testing
子目錄會包含儀表板結果的子目錄,其名稱對應於儀表板時間。Testing
子目錄也會包含一個名為Temporary
的臨時測試結果子目錄。- 更新
執行原始碼的原始碼控制更新(通常用於夜間或持續執行)。目前,CTest 支援並行版本系統 (CVS)、Subversion、Git、Mercurial 和 Bazaar。
- 設定
在專案上執行 CMake,以確保 Makefiles 或專案檔案是最新的。
- 建置
使用指定的產生器建置軟體。
- 測試
執行所有測試並記錄結果。
- 記憶體檢查
使用 Purify 或 valgrind 執行記憶體檢查。
- 涵蓋率
使用 gcov 或 Bullseye 收集原始碼涵蓋率資訊。
- 提交
將測試結果作為儀表板條目提交至伺服器。
對於夜間或實驗性條目,可以使用下列語法獨立執行每個步驟
ctest -D NightlyStart
ctest -D NightlyBuild
ctest -D NightlyCoverage -D NightlySubmit
或
ctest -D ExperimentalStart
ctest -D ExperimentalConfigure
ctest -D ExperimentalCoverage -D ExperimentalSubmit
或者,您可以使用快捷方式一次執行最常見的組合。CTest 定義的快捷方式包括
- ctest -D Experimental
執行開始、設定、建置、測試、涵蓋率和提交命令。
- ctest -D Nightly
執行開始、更新、設定、建置、測試、涵蓋率和提交命令。
- ctest -D Continuous
執行開始、更新、設定、建置、測試、涵蓋率和提交命令。
- ctest -D MemoryCheck
執行開始、設定、建置、記憶體檢查、涵蓋率和提交命令。
首次設定儀表板時,通常會將 -D
選項與 -V
選項結合使用。這樣可以讓您看到儀表板流程所有不同階段的輸出。同樣地,CTest 會在其二元樹中建立的 Testing/Temporary
目錄中維護記錄檔。您會在其中找到最近一次儀表板執行的記錄檔。儀表板結果 (XML 檔案) 也會儲存在 Testing
目錄中。
自訂專案的儀表板¶
CTest 有一些選項可用於控制其處理專案的方式。當 CTest 執行儀表板時,如果它在二元樹中找到 CTestCustom.ctest
檔案,則會載入這些檔案,並使用其中的設定來控制其行為。CTestCustom 檔案的語法與一般 CMake 語法相同。也就是說,此檔案中通常只會使用 set 命令。這些命令會指定 CTest 在執行測試時將考慮的屬性。
儀表板提交設定¶
您從 CDash 下載的檔案中提供了許多基本儀表板設定。您可以編輯這些初始值,並在需要時提供其他值。設定的第一個值是夜間開始時間。這是全球儀表板用來檢查其夜間原始碼副本的時間。此時間也控制著儀表板提交的分組方式。從夜間開始時間到下一個夜間開始時間的所有提交都會包含在同一個「日期」中。
# Dashboard is opened for submissions for a 24 hour period
# starting at the specified NIGHTLY_START_TIME. Time is
# specified in 24 hour format.
set (CTEST_NIGHTLY_START_TIME "01:00:00 UTC")
下一組設定控制著將測試結果提交至何處。這是 CDash 伺服器的位置。
# CDash server to submit results (used by client)
set (CTEST_DROP_METHOD http)
set (CTEST_DROP_SITE "my.cdash.org")
set (CTEST_DROP_LOCATION "/submit.php?project=KensTest")
set (CTEST_DROP_SITE_CDASH TRUE)
CTEST_DROP_SITE
指定 CDash 伺服器的位置。CDash 用戶端產生的建置和測試結果會傳送至此位置。CTEST_DROP_LOCATION
是伺服器上 CDash 用戶端留下其建置和測試報告的目錄或 HTTP URL。CTEST_DROP_SITE_CDASH
指定目前伺服器是 CDash,這可防止 CTest 嘗試「觸發」提交(如果此變數未設定,仍會執行此操作,以便與 Dart 和 Dart 2 向後相容)。
目前 CDash 僅支援 HTTP 提交方法;然而 CTest 支援其他提交類型。CTEST_DROP_METHOD
指定用於提交測試結果的方法。最常見的設定是 HTTP,它使用超文本傳輸協定 (HTTP) 將測試資料傳輸到伺服器。其他提交方法支援特殊情況,例如 FTP 和 SCP。在下面的範例中,使用 HTTP 協定提交結果的用戶端使用網址作為其提交站點。如果透過 FTP 提交,則此位置相對於 CTEST_DROP_SITE_USER
預設登入的位置。CTEST_DROP_SITE_USER
指定用戶端將在伺服器上使用的 FTP 使用者名稱。對於 FTP 提交,此使用者通常為「anonymous」。但是,可以使用任何可以與伺服器通信的使用者名稱。對於需要密碼的 FTP 伺服器,可以將其儲存在 CTEST_DROP_SITE_PASSWORD
變數中。CTEST_DROP_SITE_MODE
(在此範例中未使用) 是一個可選變數,可用於指定 FTP 模式。大多數 FTP 伺服器會處理預設的被動模式,但如果您的伺服器不支援,您可以明確將模式設定為主動。
CTest 也可以在防火牆後執行。如果防火牆允許 FTP 或 HTTP 流量,則不需要其他設定。如果防火牆需要 FTP/HTTP Proxy 或使用 SOCKS4 或 SOCKS5 類型的 Proxy,則需要設定一些環境變數。HTTP_PROXY 和 FTP_PROXY 指定處理 HTTP 和 FTP Proxy 請求的伺服器。HTTP_PROXY_PORT 和 FTP_PROXY_PORT 指定 HTTP 和 FTP Proxy 所在的埠。HTTP_PROXY_TYPE 指定使用的 HTTP Proxy 的類型。支援的三種不同 Proxy 類型為預設值,其中包括一般 HTTP/FTP Proxy、「SOCKS4」和「SOCKS5」,它們指定 SOCKS4 和 SOCKS5 相容的 Proxy。
篩選錯誤和警告¶
預設情況下,CTest 有一個正規表示式列表,它會匹配這些表示式以從組建過程的輸出中找到錯誤和警告。您可以使用如下所示的幾個變數,在您的 CTestCustom.ctest
檔案中覆寫這些設定。
set (CTEST_CUSTOM_WARNING_MATCH
${CTEST_CUSTOM_WARNING_MATCH}
"{standard input}:[0-9][0-9]*: Warning: "
)
set (CTEST_CUSTOM_WARNING_EXCEPTION
${CTEST_CUSTOM_WARNING_EXCEPTION}
"tk8.4.5/[^/]+/[^/]+.c[:\"]"
"xtree.[0-9]+. : warning C4702: unreachable code"
"warning LNK4221"
"variable .var_args[2]*. is used before its value is set"
"jobserver unavailable"
)
CTestCustom 檔案的另一個有用功能是,您可以使用它來限制為記憶體檢查儀表板執行的測試。使用 purify 或 valgrind 進行記憶體檢查是一個 CPU 密集型過程,對於通常需要一小時的儀表板,可能需要 20 小時。為了幫助緩解這個問題,CTest 允許您將某些測試從記憶體檢查過程中排除,如下所示
set (CTEST_CUSTOM_MEMCHECK_IGNORE
${CTEST_CUSTOM_MEMCHECK_IGNORE}
TestSetGet
otherPrint-ParaView
Example-vtkLocal
Example-vtkMy
)
排除測試的格式很簡單,就是當使用 add_test
在 CMakeLists 檔案中新增測試時指定的測試名稱列表。
除了示範的設定 (例如 CTEST_CUSTOM_WARNING_MATCH
、CTEST_CUSTOM_WARNING_EXCEPTION
和 CTEST_CUSTOM_MEMCHECK_IGNORE
) 之外,CTest 還會檢查其他幾個變數。
- CTEST_CUSTOM_ERROR_MATCH
將組建行視為錯誤行的其他正規表示式
- CTEST_CUSTOM_ERROR_EXCEPTION
將組建行視為非錯誤行的其他正規表示式
- CTEST_CUSTOM_WARNING_MATCH
將組建行視為警告行的其他正規表示式
- CTEST_CUSTOM_WARNING_EXCEPTION
將組建行視為非警告行的其他正規表示式
- CTEST_CUSTOM_MAXIMUM_NUMBER_OF_ERRORS
在 CTest 停止報告錯誤之前,允許的最大錯誤數 (預設值為 50)
- CTEST_CUSTOM_MAXIMUM_NUMBER_OF_WARNINGS
在 CTest 停止報告警告之前,允許的最大警告數 (預設值為 50)
- CTEST_CUSTOM_COVERAGE_EXCLUDE
從覆蓋率分析中排除的檔案的正規表示式
- CTEST_CUSTOM_PRE_MEMCHECK
在執行記憶體檢查之前要執行的命令列表
- CTEST_CUSTOM_POST_MEMCHECK
在執行記憶體檢查之後要執行的命令列表
- CTEST_CUSTOM_MEMCHECK_IGNORE
要從記憶體檢查步驟中排除的測試列表
- CTEST_CUSTOM_PRE_TEST
在執行測試之前要執行的命令列表
- CTEST_CUSTOM_POST_TEST
在執行測試之後要執行的命令列表
- CTEST_CUSTOM_TESTS_IGNORE
要從測試步驟中排除的測試列表
- CTEST_CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE
通過測試的測試輸出的最大大小 (預設值為 1k)
- CTEST_CUSTOM_MAXIMUM_FAILED_TEST_OUTPUT_SIZE
失敗測試的測試輸出的最大大小 (預設值為 300k)
在 CTEST_CUSTOM_PRE_TEST
和 CTEST_CUSTOM_POST_TEST
中指定的命令以及等效的記憶體檢查命令,每個 CTest 執行一次。例如,如果所有測試都需要執行一些初始設定和一些最終清除,則可以使用這些命令。
將註解新增至儀表板¶
CTest 和 CDash 支援將註解檔案新增至儀表板提交。這些檔案將在儀表板上顯示為可點擊的圖示,該圖示連結到所有檔案的文字。若要新增註解,請使用 -A 選項並加上以分號分隔的檔案名稱列表來呼叫 CTest。這些檔案的內容將作為儀表板的註解提交。例如
ctest -D Continuous -A C:/MyNotes.txt;C:/OtherNotes.txt
提交儀表板註解的另一種方法是將註解作為檔案複製或寫入二進位樹的 Testing
目錄下的 Notes 目錄。當 CTest 提交儀表板時,在此處找到的任何檔案也會上傳為註解。
CTest 腳本¶
本節說明如何編寫基於命令的 CTest 腳本,讓維護人員可以精細地控制儀表板的個別步驟。
儀表板維護人員可以存取個別 CTest 命令函數,例如 ctest_configure
和 ctest_build
。透過單獨執行這些函數,使用者可以彈性地開發自訂測試方案。以下是 CTest 腳本的範例
cmake_minimum_required(VERSION 3.20)
set(CTEST_SITE "andoria.kitware")
set(CTEST_BUILD_NAME "Linux-g++")
set(CTEST_NOTES_FILES
"${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
set(CTEST_DASHBOARD_ROOT "$ENV{HOME}/Dashboards/My Tests")
set(CTEST_SOURCE_DIRECTORY "${CTEST_DASHBOARD_ROOT}/CMake")
set(CTEST_BINARY_DIRECTORY "${CTEST_DASHBOARD_ROOT}/CMake-gcc ")
set(CTEST_UPDATE_COMMAND "/usr/bin/cvs")
set(CTEST_CONFIGURE_COMMAND
"\"${CTEST_SOURCE_DIRECTORY}/bootstrap\"")
set(CTEST_BUILD_COMMAND "/usr/bin/make -j 2")
ctest_empty_binary_directory(${CTEST_BINARY_DIRECTORY})
ctest_start(Nightly)
ctest_update(SOURCE "${CTEST_SOURCE_DIRECTORY}")
ctest_configure(BUILD "${CTEST_BINARY_DIRECTORY}")
ctest_build(BUILD "${CTEST_BINARY_DIRECTORY}")
ctest_test(BUILD "${CTEST_BINARY_DIRECTORY}")
ctest_submit()
第一個區塊包含有關提交的變數。
set(CTEST_SITE "andoria.kitware")
set(CTEST_BUILD_NAME "Linux-g++")
set(CTEST_NOTES_FILES
"${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
這些變數用於在系統將結果提交至儀表板後識別系統。CTEST_NOTES_FILES
是應該作為儀表板提交的註解提交的檔案列表。此變數對應於 ctest
的 -A 旗標。
第二個區塊描述 CTest 函數將用於執行工作的功能資訊
set(CTEST_DASHBOARD_ROOT "$ENV{HOME}/Dashboards/My Tests")
set(CTEST_SOURCE_DIRECTORY "${CTEST_DASHBOARD_ROOT}/CMake")
set(CTEST_BINARY_DIRECTORY "${CTEST_DASHBOARD_ROOT}/CMake-gcc ")
set(CTEST_UPDATE_COMMAND "/usr/bin/cvs")
set(CTEST_CONFIGURE_COMMAND
"\"${CTEST_SOURCE_DIRECTORY}/bootstrap\"")
set(CTEST_BUILD_COMMAND "/usr/bin/make -j 2")
CTEST_UPDATE_COMMAND
是用於從儲存庫更新來源目錄的命令路徑。目前,CTest 支援 Concurrent Versions System (CVS)、Subversion、Git、Mercurial 和 Bazaar。
設定和組建處理常式都支援兩種模式。一種模式是提供在該階段期間呼叫的完整命令。此模式旨在支援未使用 CMake 作為其設定或組建工具的專案。在這種情況下,您可以分別透過設定 CTEST_CONFIGURE_COMMAND
和 CTEST_BUILD_COMMAND
變數,來指定設定和組建專案的完整命令列。
對於組建步驟,您還應該設定變數 CTEST_PROJECT_NAME
和 CTEST_BUILD_CONFIGURATION
,以指定如何組建專案。在這種情況下,CTEST_PROJECT_NAME
將會符合頂層 CMakeLists 檔案的 project
命令。CTEST_BUILD_CONFIGURATION
應該是 Release、Debug、MinSizeRel 或 RelWithDebInfo 之一。此外,可以提供 CTEST_BUILD_FLAGS
作為組建命令的提示。測試基於 CMake 的專案的範例為
set(CTEST_PROJECT_NAME "Grommit")
set(CTEST_BUILD_CONFIGURATION "Debug")
最後一個區塊會執行實際的測試和提交
ctest_empty_binary_directory(${CTEST_BINARY_DIRECTORY})
ctest_start(Nightly)
ctest_update(SOURCE
"${CTEST_SOURCE_DIRECTORY}" RETURN_VALUE res)
ctest_configure(BUILD
"${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res)
ctest_build(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res)
ctest_test(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res)
ctest_submit(RETURN_VALUE res)
ctest_empty_binary_directory
命令會清空目錄和所有子目錄。請注意,此命令內建了安全措施,那就是只有在頂層目錄中存在 CMakeCache.txt 檔案時才會移除目錄。這是為了防止 CTest 誤移除非組建目錄。
區塊的其餘部分包含對實際 CTest 函數的呼叫。它們每一個都對應於 CTest -D 選項。例如,而不是
ctest -D ExperimentalBuild
腳本將包含
ctest_start(Experimental)
ctest_build(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res)
每個步驟都會產生一個傳回值,指示該步驟是否成功。例如,可以在持續儀表板中使用更新階段的傳回值,以判斷是否應該執行儀表板的其餘部分。
讓我們來檢視一個更進階的 CTest 腳本。此腳本會驅動名為 Slicer 的應用程式的測試。Slicer 在內部使用 CMake,但它會透過一系列 Tcl 腳本來驅動組建過程。這種方法的問題之一是不支援來源外組建。此外,在 Windows 上,某些模組是預先組建的,因此必須將它們複製到組建目錄。若要測試這樣的專案,我們將使用如下所示的腳本
cmake_minimum_required(VERSION 3.20)
# set the dashboard specific variables -- name and notes
set(CTEST_SITE "dash11.kitware")
set(CTEST_BUILD_NAME "Win32-VS71")
set(CTEST_NOTES_FILES
"${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}")
# do not let any single test run for more than 1500 seconds
set(CTEST_TIMEOUT "1500")
# set the source and binary directories
set(CTEST_SOURCE_DIRECTORY "C:/Dashboards/MyTests/slicer2")
set(CTEST_BINARY_DIRECTORY "${CTEST_SOURCE_DIRECTORY}-build")
set (SLICER_SUPPORT
"//Dash11/Shared/Support/SlicerSupport/Lib")
set (TCLSH "${SLICER_SUPPORT}/win32/bin/tclsh84.exe")
# set the complete update, configure and build commands
set (CTEST_UPDATE_COMMAND
"C:/Program Files/TortoiseCVS/cvs.exe")
set (CTEST_CONFIGURE_COMMAND
"\"${TCLSH}\"
\"${CTEST_BINARY_DIRECTORY}/Scripts/genlib.tcl\"")
set (CTEST_BUILD_COMMAND
"\"${TCLSH}\"
\"${CTEST_BINARY_DIRECTORY}/Scripts/cmaker.tcl\"")
# clear out the binary tree
file (WRITE "${CTEST_BINARY_DIRECTORY}/CMakeCache.txt"
"// Dummy cache just so that ctest will wipe binary dir")
ctest_empty_binary_directory (${CTEST_BINARY_DIRECTORY})
# special variables for the Slicer build process
set (ENV{MSVC6} "0")
set (ENV{GENERATOR} "Visual Studio 7 .NET 2003")
set (ENV{MAKE} "devenv.exe ")
set (ENV{COMPILER_PATH}
"C:/Program Files/Microsoft Visual Studio .NET
2003/Common7/Vc7/bin")
set (ENV{CVS} "${CTEST_UPDATE_COMMAND}")
# start and update the dashboard
ctest_start (Nightly)
ctest_update (SOURCE "${CTEST_SOURCE_DIRECTORY}")
# define a macro to copy a directory
macro (COPY_DIR srcdir destdir)
exec_program ("${CMAKE_EXECUTABLE_NAME}" ARGS
"-E copy_directory \"${srcdir}\" \"${destdir}\"")
endmacro ()
# Slicer does not support out of source builds so we
# first copy the source directory to the binary directory
# and then build it
copy_dir ("${CTEST_SOURCE_DIRECTORY}"
"${CTEST_BINARY_DIRECTORY}")
# copy support libraries that slicer needs into the binary tree
copy_dir ("${SLICER_SUPPORT}"
"${CTEST_BINARY_DIRECTORY}/Lib")
# finally do the configure, build, test and submit steps
ctest_configure (BUILD "${CTEST_BINARY_DIRECTORY}")
ctest_build (BUILD "${CTEST_BINARY_DIRECTORY}")
ctest_test (BUILD "${CTEST_BINARY_DIRECTORY}")
ctest_submit ()
透過擴展的 CTest 腳本,我們可以完全控制流程,因此可以在任何時間點執行任意命令。例如,在執行專案更新後,腳本會將原始碼樹複製到建置目錄中。這使其可以執行「源代碼之外」的建置。
專案角色:CDash 支援三種使用者角色等級¶
一般使用者是具有專案程式碼儲存庫讀取和/或寫入權限的常規使用者。
站點維護者負責定期向 CDash 提交內容。
專案管理員擁有在 CDash 中管理專案的保留權限。
前兩個等級可以由使用者自行定義。專案管理員存取權必須由專案的另一位管理員或 CDash 伺服器管理員授予。
提交備份¶
CDash 預設會備份所有傳入的 XML 提交,並將其放置在 backup
目錄中。預設的時間範圍為 48 小時。可以在 config.local.php
中變更時間範圍,如下所示
$CDASH_BACKUP_TIMEFRAME=72;
如果專案是私有的,建議將備份目錄設置在 apache 根目錄之外,以確保沒有人可以訪問 XML 檔案,或是在備份目錄中的 .htaccess 中添加以下行
<Files *>
order allow,deny
deny from all
</Files>
請注意,只有在新提交到達時才會清空備份目錄。如有必要,CDash 也可以從備份目錄匯入建置。
建置群組¶
建置可以按群組組織。在 CDash 中,會自動定義三個群組且無法移除:Nightly
、Continuous
和 Experimental
。這些群組與 CTest 強制的群組相同。每個群組都有一個相關聯的描述,該描述會在主儀表板上點擊群組名稱時顯示。
預設情況下,建置會屬於與 CTest 定義的建置類型相關聯的群組,即,夜間建置會進入 Nightly 部分。CDash 會依據其名稱、站點和建置類型來匹配建置。例如,來自「midworld.kitware」站點的夜間建置,名稱為「Linux-gcc-4.3」,除非定義了「Linux-gcc-4.3」-「midworld.kitware」-「Nightly」的規則,否則會移動到 Nightly 部分。有兩種方法可以透過定義規則將建置移動到給定的群組:全域移動和單一移動。
單一移動允許僅修改特定建置¶
如果以專案管理員身分登入,則會在主儀表板頁面上每個建置的旁邊顯示一個小的資料夾圖示。點擊圖示會顯示每個建置的一些選項。特別是,專案管理員可以將建置標記為預期、將建置移動到特定群組,或刪除虛假的建置。
預期建置:專案管理員可以將某些建置標記為預期。這表示每天預期會提交建置。這讓您可以快速檢查是否有建置未在今天的儀表板上提交,或透過點擊主儀表板上的資訊圖示來快速評估建置已遺失多久。
如果前一天沒有提交預期的建置,並且已為專案勾選「遺失建置的電子郵件」選項,則會向站點維護者和專案管理員發送電子郵件以提醒他們(有關更多資訊,請參閱「站點」部分)。
電子郵件¶
當給定建置發生故障時,CDash 會向開發人員和專案管理員發送電子郵件。電子郵件功能的配置位於三個位置:config.local.php
檔案、專案管理部分和專案的群組部分。
在 config.local.php
中,定義了兩個變數以指定發送電子郵件的電子郵件地址和回覆地址。請注意,在目前版本的 CDash 中無法定義 SMTP 伺服器,它假設在本機上執行電子郵件伺服器。
$CDASH_EMAIL_FROM = 'admin@mywebsite.com';
$CDASH_EMAIL_REPLY = 'noreply@mywebsite.com';
在專案的電子郵件配置部分中,可以調整多個參數來控制電子郵件功能。
在專案的「建置群組」管理部分中,管理員可以決定是否將電子郵件發送到特定群組,或是否僅應發送摘要電子郵件。當目前至少有一個建置在當天失敗時,會針對給定的群組發送摘要電子郵件。
站點¶
CDash 將站點稱為向給定專案提交至少一個建置的單一機器。一個站點可能會向 CDash 中儲存的多個專案提交多個建置(例如,夜間和持續建置)。
為了查看站點描述,請從專案的主儀表板頁面點擊站點的名稱。站點的描述包括有關處理器類型和速度以及給定機器上可用記憶體容量的資訊。站點的描述會由 CTest 自動發送,但在某些情況下,可能需要手動編輯。此外,如果機器已升級,即記憶體已升級;CDash 會追蹤描述的歷史記錄,讓使用者可以比較升級前後的效能。
站點通常屬於一位維護者,負責向 CDash 提交內容。當站點未提交時,警告站點維護者很重要,因為這可能與配置問題有關。
一旦聲明了站點,如果用戶端機器由於未知原因未提交,其維護者將會收到電子郵件,前提是該站點預計會每晚提交。此外,該站點將會出現在維護者個人資料的「我的站點」部分中,方便快速檢查站點的狀態。
站點頁面的另一個功能是顯示機器負載的圓形圖。假設一個站點提交到多個專案,通常了解機器是否有空間可以向 CDash 提交其他內容會很有用。圓形圖提供了每個專案的機器提交時間的概觀。
圖表¶
CDash 目前繪製三種類型的圖表。圖表是從資料庫記錄動態產生,並且是互動式的。
建置時間圖表會顯示隨著時間推移建置專案所需的時間。
測試時間圖表會顯示執行特定測試的時間以及其隨著時間推移的狀態(通過/失敗)。
向建置新增註解¶
在某些情況下,通知其他開發人員有人正在查看建置的錯誤會很有用。
記錄¶
CDash 支援使用 error_log() PHP 函數的內部記錄機制。任何嚴重的 SQL 錯誤都會被記錄。預設情況下,CDash 記錄檔位於備份目錄中,名稱為 cdash.log
。可以透過變更 config.local.php
設定檔中的變數來修改記錄檔的位置。
$CDASH_BACKUP_DIRECTORY='/var/temp/cdashbackup/log';
如果記錄檔位於標準位置,則可以直接從 CDash 存取記錄檔。
提供了一種記錄輪換機制,允許使用者將目前的記錄檔限制為特定大小。
測試計時¶
CDash 支援檢查測試的持續時間。CDash 會在資料庫中保留每個測試執行時間的平均值和標準差的當前加權平均值。為了盡可能提高計算效率,使用了以下公式,其中僅涉及先前的建置。
// alpha is the current "window" for the computation
// By default, alpha is 0.3
newMean = (1-alpha)*oldMean + alpha*currentTime
newSD = sqrt((1-alpha)*SD*SD +
alpha*(currentTime-newMean)*(currentTime-newMean)
根據以下邏輯,將測試定義為計時失敗
if previousSD < thresholdSD then previousSD = thresholdSD
if currentTime > previousMean+multiplier*previousSD then fail
行動裝置支援¶
由於 CDash 是使用透過 XSLT 的範本層編寫的,因此開發新的版面配置就像新增新的渲染範本一樣簡單。作為示範,目前的 CDash 版本中提供了 iPhone Web 範本。
http://mycdashserver/CDash/iphone
主頁會顯示伺服器上託管的公開專案清單。點擊專案名稱會載入其目前的儀表板。同樣,點擊給定的建置會顯示有關該建置的更詳細資訊。在撰寫本文時,此版面配置不支援登入以及存取 CDash 的私人部分。
備份 CDash¶
CDash 使用的所有資料(記錄除外)都儲存在其資料庫中。定期備份資料庫很重要,尤其是在執行 CDash 升級之前。有幾種方法可以備份 MySQL 資料庫。最簡單的方法是使用 mysqldump 命令
mysqldump -r cdashbackup.sql cdash
如果您僅使用 MyISAM 表格,則可以將 MySQL 資料目錄中的 CDash 目錄複製出來。請注意,您需要在複製之前關閉 MySQL,這樣在複製過程中就不會變更任何檔案。與 MySQL 類似,PostGreSQL 也有 pg_dump 公用程式
pg_dump -U posgreSQL_user cdash > cdashbackup.sql
升級 CDash¶
當發布新版本的 CDash 時,或如果您決定從儲存庫更新時,如果目前資料庫需要升級,CDash 會在首頁上警告您。升級到新版本時,應採取以下步驟
備份您的 SQL 資料庫(請參閱上一節)。
備份您的
config.local.php
(或config.php
)設定檔。將您目前的 cdash 目錄替換為最新版本,並將
config.local.php
複製到 cdash 目錄中。將您的瀏覽器導覽到您的 CDash 頁面。(例如,https://127.0.0.1/CDash)。
請注意首頁上的版本號碼,它應與您要升級的版本相符。
可能會出現以下訊息:「目前的資料庫結構描述與您正在執行的 CDash 版本不符,請在 CDash 的管理面板中升級您的資料庫結構。」這是一個有用的提醒,可讓您執行以下步驟。
以管理員身分登入 CDash。
在「管理」部分中,按一下「[CDash 維護]」。
按一下「升級 CDash」:此程序可能需要一些時間,具體取決於資料庫的大小(請勿關閉瀏覽器)。
在 CDash 執行升級時,可能會顯示進度訊息。
如果升級程序耗時過長,您可以在
backup/cdash.log
檔案中查看程序耗時過長和/或失敗的地方。據報告,在某些系統上,旋轉圖示永遠不會變成勾號。如果您認為升級耗時過長,請在
cdash.log
中檢查「Upgrade done.」字串。在 50GB 的資料庫上,升級可能需要長達 2 小時。
某些 Web 瀏覽器在升級時可能會出現問題(某些 javascript 變數未正確傳遞),在這種情況下,您可以執行單獨的更新。例如,從 CDash 1-2 升級到 1-4
http://mywebsite.com/CDash/backwardCompatibilityTools.php?upgrade-1-4=1
CDash 維護¶
資料庫維護:我們建議您定期執行資料庫最佳化(重新索引、清除等),以維持資料庫的穩定性。MySQL 有一個名為 mysqlcheck
的工具,而 PostgreSQL 有幾個工具,例如 vacuumdb
。
刪除日期不正確的建置:某些建置可能會因為 XML 檔案中的日期不正確,或 CDash(主要是由 PHP)無法辨識時區,而以錯誤的日期提交到 CDash。這些建置將不會顯示在任何儀表板中,因為開始時間是錯誤的。為了移除這些建置
以管理員身分登入 CDash。
請在管理區塊中點擊 [CDash 維護]。
點擊「刪除開始日期錯誤的建置」。
重新計算測試時間:如果您剛升級 CDash,您可能會注意到目前的提交顯示大量的測試失敗,原因是時間缺陷。這是因為 CDash 沒有足夠的樣本點來計算每個測試的平均值和標準差,特別是標準差可能非常小(對於前幾個樣本可能為零)。您應該關閉「啟用測試時間」約一週,或者直到您獲得足夠的建置提交,且 CDash 已計算出每個測試時間的近似平均值和標準差。
另一個選擇是強制 CDash 計算過去幾天每個測試的平均值和標準差。請注意,此過程可能需要很長時間,具體取決於涉及的測試和專案數量。為了重新計算測試時間
以管理員身分登入 CDash。
請在管理區塊中點擊 [CDash 維護]。
指定要重新計算測試時間的天數(預設為 4 天)。
點擊「計算測試時間」。完成此過程後,在此期間提交的測試的新平均值、標準差和狀態應該會更新。
自動移除建置¶
為了使資料庫保持在合理的大小,CDash 可以自動清除舊的建置。目前有兩種方法可以設定自動移除建置:無需 cronjob,請編輯 config.local.php
並新增/編輯以下行
$CDASH_AUTOREMOVE_BUILDS='1';
CDash 會在每天的第一次提交時自動移除建置。請注意,移除建置可能會增加資料庫的額外負載,或者如果您的資料庫很大且提交數量很多,則會減慢目前的提交過程。如果您可以使用 cronjob,則可以使用 PHP 命令列工具在方便的時間觸發建置移除。例如,在每週日早上 6 點移除所有專案的建置
0 6 * * 0 php5 /var/www/CDash/autoRemoveBuilds.php all
請注意,「all」參數可以更改為特定的專案名稱,以便從單一專案中清除建置。
CDash XML 綱要¶
CDash 中的 XML 解析器可以輕鬆擴展以支援新功能。CTest 產生的目前 XML 綱要,以及書中描述的功能,位於
http://public.kitware.com/Wiki/CDash:XML
子專案¶
CDash 支援將專案分割成子專案。某些子專案可能反過來依賴其他子專案。一個典型的真實專案由函式庫、可執行檔、測試套件、文件、網頁和安裝程式組成。將您的專案組織成定義良好的子專案,並在 CDash 儀表板上呈現夜間建置的結果,有助於識別不同粒度層級的問題所在。
具有子專案的專案,其頂層 CDash 頁面的檢視方式與沒有任何子專案的專案不同。它包含整個專案的摘要列,然後為每個子專案包含一個摘要列。
組織和定義子專案¶
若要將子專案組織新增至您的專案,您必須:(1) 為 CDash 定義子專案,以便它知道如何正確顯示它們,以及 (2) 使用具有 CTest 的建置腳本來提交專案的子專案建置。您的專案的 CMakeLists.txt 檔案可能也需要進行一些(重新)組織,以允許按子專案建置您的專案。
有兩種方法可以定義子專案及其依賴關係:在以專案管理員身分登入時於 CDash GUI 中互動式地定義,或透過提交描述子專案和依賴關係的 Project.xml
檔案來定義。
互動式地新增子專案¶
作為專案管理員,在「我的 CDash」頁面上,您的每個專案都會出現一個「管理子專案」按鈕。點擊「管理子專案」按鈕會開啟管理子專案頁面,您可以在其中為您是管理員的任何專案新增新的子專案或建立現有子專案之間的依賴關係。
自動新增子專案¶
定義 CDash 子專案及其依賴關係的另一種方法是,與 CTest 在將建置提交到 CDash 時傳送的常用提交檔案一起提交「Project.xml」檔案。若要定義與上述互動式範例中相同的兩個子專案(Exes 和 Libs),並具有相同的依賴關係(Exes 依賴 Libs),Project.xml
檔案看起來會像以下範例
<Project name="Tutorial">
<SubProject name="Libs"></SubProject>
<SubProject name="Exes">
<Dependency name="Libs">
</SubProject>
</Project>
一旦編寫或產生 Project.xml
檔案後,可以使用 ctest_submit
命令的 FILES 引數,從 ctest -S 腳本將其提交到 CDash,或直接從為儀表板提交配置的建置樹中的 ctest
命令列提交。
從 ctest -S 腳本內部
ctest_submit(FILES "${CTEST_BINARY_DIRECTORY}/Project.xml")
從命令列
cd ../Project-build
ctest --extra-submit Project.xml
CDash 會根據 Project.xml
檔案自動新增子專案和依賴關係。CDash 也會移除 Project.xml
檔案中未定義的任何子專案或依賴關係。此外,如果多次提交相同的 Project.xml
,則第二次和後續提交不會產生可觀察到的影響:第一次提交會新增/修改資料,第二次和後續提交會傳送相同的資料,因此無需進行任何變更。CDash 會追蹤子專案定義的變更,以便專案隨著時間的推移發展。如果您從過去的日期檢視儀表板,CDash 將根據該日期生效的子專案定義呈現專案/子專案檢視。
將 ctest_submit 與 PARTS 和 FILES 搭配使用¶
ctest_submit
命令支援 PARTS
和 FILES
引數。透過 PARTS
,您可以使用每個 ctest_submit
呼叫傳送 XML 檔案的任何子集。依預設,所有可用的部分都會在任何對 ctest_submit
的呼叫中傳送。腳本可以等到所有儀表板階段完成,然後呼叫 ctest_submit
一次,以便在執行結束時傳送所有階段的結果。或者,腳本可以使用 PARTS
呼叫 ctest_submit
,以執行結果子集的局部提交。例如,您可以在 ctest_configure
之後提交設定結果,在 ctest_build
之後提交建置結果,以及在 ctest_test
之後提交測試結果。這樣可以隨著建置的進度發布資訊。
透過 FILES
,您可以將任意 XML 檔案傳送至 CDash。除了 CTest 傳送的標準建置結果 XML 檔案之外,CDash 也會處理描述子專案和依賴關係的 Project.xml
檔案。以下是一個儀表板腳本的範例,該腳本在其最後一行包含單一 ctest_submit
呼叫
ctest_start(Experimental)
ctest_update(SOURCE "${CTEST_SOURCE_DIRECTORY}")
ctest_configure(BUILD "${CTEST_BINARY_DIRECTORY}")
ctest_build(BUILD "${CTEST_BINARY_DIRECTORY}")
ctest_test(BUILD "${CTEST_BINARY_DIRECTORY}")
ctest_submit()
提交可以遞增地發生,提交的每個部分都會在其可用時逐步傳送
ctest_start(Experimental)
ctest_update(SOURCE "${CTEST_SOURCE_DIRECTORY}")
ctest_configure(BUILD "${CTEST_BINARY_DIRECTORY}")
ctest_submit(PARTS Update Configure Notes)
ctest_build(BUILD "${CTEST_BINARY_DIRECTORY}" APPEND)
ctest_submit(PARTS Build)
ctest_test(BUILD "${CTEST_BINARY_DIRECTORY}")
ctest_submit(PARTS Test)
以部分遞增方式提交,表示您可以在建置仍在進行時,即時在 CDash 儀表板上檢視組態階段的結果。同樣地,您也可以在測試仍在執行時,即時檢視建置階段的結果。當以部分提交時,在 ctest_build
命令中,使用 APPEND
關鍵字非常重要。如果您不使用 APPEND
,當 CDash 收到 Build.xml 檔案時,會清除任何具有相同建置名稱、站點名稱和建置時間戳記的現有建置。
將您的專案分割為多個子專案¶
一個 ctest_build
調用來建置所有內容,接著一個 ctest_test
調用來測試所有內容,對於沒有子專案的專案來說已經足夠,但如果您想以每個子專案為基礎將結果提交至 CDash,則必須對您的專案和測試腳本進行一些變更。對於您的專案,您需要識別哪些目標屬於哪些子專案。如果您組織您的 CMakeLists 檔案,讓每個子專案都有一個要建置的目標,並且您可以根據子專案名稱推導(或查找)該目標的名稱,那麼修改您的腳本以將其分成多個較小的組態/建置/測試區塊應該相對容易。為此,您可以根據您的需求以各種方式修改您的 CMakeLists 檔案。以下列出最常見的變更。
CMakeLists.txt 修改¶
將目標命名為與子專案相同,或根據子專案名稱命名基本目標名稱,或提供查找機制以將子專案名稱對應到目標名稱。
可能新增自訂目標以將現有目標聚合到子專案中,使用
add_dependencies
來指定自訂目標依賴哪些現有目標。將
LABELS
目標屬性新增至目標,並使用子專案名稱的值。將
LABELS
測試屬性新增至測試,並使用子專案名稱的值。
接下來,您需要修改執行儀表板的 CTest 腳本。要將您一個大型的整體建置分割成較小的子專案建置,您可以在 CTest 驅動程式腳本中使用 foreach
迴圈。為了協助您迭代您的子專案,CDash 在 CTestConfig.cmake
中提供一個名為 CTEST_PROJECT_SUBPROJECTS
的變數。以上述範例為例,CDash 會產生類似以下的變數
set(CTEST_PROJECT_SUBPROJECTS Libs Exes)
CDash 會對此清單中的元素進行排序,使得獨立的子專案(不依賴於任何其他子專案)排在最前面,接著是僅依賴於獨立子專案的子專案,然後是依賴於這些子專案的子專案。相同的邏輯會持續到此清單中列出所有子專案一次,並且其順序適合依序逐個建置。
為了方便只建置與子專案相關的目標,請使用名為 CTEST_BUILD_TARGET
的變數來告訴 ctest_build
要建置的內容。為了方便只執行與子專案相關的測試,請將 LABELS
測試屬性指定給您的測試,並使用 INCLUDE_LABEL
引數給 ctest_test
。
ctest 驅動程式腳本修改¶
依賴順序(從獨立到最依賴的...)迭代子專案。
設定子專案和標籤全域屬性 – CTest 會使用這些屬性將結果提交到 CDash 伺服器上的正確子專案。
建置此子專案的目標:從子專案名稱計算要建置的目標名稱,設定
CTEST_BUILD_TARGET
,呼叫ctest_build
。使用
INCLUDE
或INCLUDE_LABEL
引數給ctest_test
,執行此子專案的測試。使用
ctest_submit
與PARTS
引數,以在完成時提交部分結果。
為了說明這一點,以下範例顯示將建置分割成較小部分所需的變更。假設子專案名稱與建置子專案元件所需的目標名稱相同。例如,以下是假設 Tutorial 專案中 CMakeLists.txt 的程式碼片段。唯一必要的額外項目(因為目標名稱與子專案名稱相同)是針對每個目標和每個測試呼叫 set_property
。
# "Libs" is the library name (therefore a target name) and
# the subproject name
add_library (Libs ...)
set_property (TARGET Libs PROPERTY LABELS Libs)
add_test (LibsTest1 ...)
add_test (LibsTest2 ...)
set_property (TEST LibsTest1 LibsTest2 PROPERTY LABELS Libs)
# "Exes" is the executable name (therefore a target name)
# and the subproject name
add_executable (Exes ...)
target_link_libraries (Exes Libs)
set_property (TARGET Exes PROPERTY LABELS Exes)
add_test (ExesTest1 ...)
add_test (ExesTest2 ...)
set_property (TEST ExesTest1 ExesTest2 PROPERTY LABELS Exes)
以下是在將此專案組織成子專案之前和之後,CTest 驅動程式腳本可能看起來的範例。變更前
ctest_start (Experimental)
ctest_update (SOURCE "${CTEST_SOURCE_DIRECTORY}")
ctest_configure (BUILD "${CTEST_BINARY_DIRECTORY}")
# builds *all* targets: Libs and Exes
ctest_build (BUILD "${CTEST_BINARY_DIRECTORY}")
# runs *all* tests
ctest_test (BUILD "${CTEST_BINARY_DIRECTORY}")
# submits everything all at once at the end
ctest_submit ()
變更後
ctest_start (Experimental)
ctest_update (SOURCE "${CTEST_SOURCE_DIRECTORY}")
ctest_submit (PARTS Update Notes)
# to get CTEST_PROJECT_SUBPROJECTS definition:
include ("${CTEST_SOURCE_DIRECTORY}/CTestConfig.cmake")
foreach (subproject ${CTEST_PROJECT_SUBPROJECTS})
set_property (GLOBAL PROPERTY SubProject ${subproject})
set_property (GLOBAL PROPERTY Label ${subproject})
ctest_configure (BUILD "${CTEST_BINARY_DIRECTORY}")
ctest_submit (PARTS Configure)
set (CTEST_BUILD_TARGET "${subproject}")
ctest_build (BUILD "${CTEST_BINARY_DIRECTORY}" APPEND)
# builds target ${CTEST_BUILD_TARGET}
ctest_submit (PARTS Build)
ctest_test (BUILD "${CTEST_BINARY_DIRECTORY}"
INCLUDE_LABEL "${subproject}"
)
# runs only tests that have a LABELS property matching
# "${subproject}"
ctest_submit (PARTS Test)
endforeach ()
在某些專案中,可能需要多個 ctest_build
步驟來建置子專案的所有部分。例如,在 Trilinos 中,每個子專案都會建置 ${subproject}_libs target
,然後建置所有目標,以建置測試套件中所有已組態的可執行檔。它們還會組態依賴項,以便在建置所有目標時,僅建置目前已組態套件需要建置的可執行檔。
通常,如果您將多個具有完全相同建置時間戳記的 Build.xml
檔案提交到 CDash,它將刪除現有項目,並將新項目新增到其位置。如果需要多個 ctest_build
步驟,每個步驟都有自己的 ctest_submit(PARTS Build)
呼叫,請在所有屬於一起的 ctest_build
呼叫中使用 APPEND
關鍵字引數。APPEND
標誌會告知 CDash 從多個提交中累積結果,並在儀表板上的一列中顯示所有結果的聚合。從 CDash 的角度來看,多個 ctest_build
呼叫(具有相同的建置時間戳記和子專案,且開啟 APPEND
)會產生單一 CDash 建置。
在您最喜歡的基於 CMake 的專案中採用這些提示和技術
LABELS
是適用於原始程式檔、目標和測試的 CMake/CTest 屬性。標籤會傳送到結果 XML 檔案內的 CDash。使用
ctest_submit(PARTS ...)
來執行遞增提交。結果會更快在儀表板上顯示。當以部分提交時,請不要忘記在您的ctest_build
呼叫中使用APPEND
。將
INCLUDE_LABEL
與ctest_test
搭配使用,以僅執行具有符合正規表示式的標籤的測試。使用
CTEST_BUILD_TARGET
來一次建置一個子專案,並在此過程中提交子專案儀表板。