diff --git a/build_functions/CMakeLists.txt b/build_functions/CMakeLists.txt index 3bfa98a..34b170d 100644 --- a/build_functions/CMakeLists.txt +++ b/build_functions/CMakeLists.txt @@ -344,6 +344,39 @@ function(build_exe whatIsBuilding solution_folder custom_main) endif() endfunction() +# Validates that *_int.c files in test_folder use TIMED_TEST_SUITE_INITIALIZE/CLEANUP. +# Skip specific folders: cmake -Dtimed_test_suite_skip_regex="module_a_int|module_b_int" +# Optional: NUM_EXPECTED_VIOLATIONS - expected number of files with violations (default 0) +function(validate_timed_test_suite test_folder) + set(options) + set(oneValueArgs NUM_EXPECTED_VIOLATIONS) + set(multiValueArgs) + cmake_parse_arguments(arg "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + if(NOT DEFINED arg_NUM_EXPECTED_VIOLATIONS) + set(arg_NUM_EXPECTED_VIOLATIONS 0) + endif() + + # Allow skipping via regex + if(DEFINED timed_test_suite_skip_regex AND NOT "${timed_test_suite_skip_regex}" STREQUAL "") + if("${test_folder}" MATCHES "${timed_test_suite_skip_regex}") + return() + endif() + endif() + + set(script_path "${trsw_internal_dir}/scripts/validate_timed_test_suite.ps1") + if(EXISTS "${script_path}") + add_custom_target(${test_folder}_timed_suite_check ALL + COMMAND powershell.exe -ExecutionPolicy Bypass + -File "${script_path}" + -TestFolder "${CMAKE_CURRENT_SOURCE_DIR}/${test_folder}" + -NumExpectedViolations ${arg_NUM_EXPECTED_VIOLATIONS} + COMMENT "Validating timed test suite in ${test_folder}" + VERBATIM + ) + endif() +endfunction() + #drop in replacement for add_subdirectory :) #test_folder is the name of a folder that exists on the drive. For example "clds_hash_table_ut". It is not a complete path. function(build_test_folder test_folder) @@ -368,6 +401,11 @@ function(build_test_folder test_folder) set(building dll) add_subdirectory(${test_folder} ${test_folder}/${arg_BINARY_DIR}/${building}) endif() + + # Validate timed test suite for integration tests + if(WIN32 AND ("${test_folder}" MATCHES ".*int.*")) + validate_timed_test_suite(${test_folder}) + endif() else() #message("test_folder is ${test_folder} NOT BUILDING") endif() @@ -404,3 +442,7 @@ function(build_test_artifacts_with_custom_main whatIsBuilding solution_folder ) MESSAGE(FATAL_ERROR "not an expected value: building=${building} test_folder=${test_folder} ARGN=${ARGN}") endif() endfunction() + +if(${run_unittests}) + add_subdirectory(tests/validate_timed_test_suite) +endif() diff --git a/build_functions/scripts/validate_timed_test_suite.ps1 b/build_functions/scripts/validate_timed_test_suite.ps1 new file mode 100644 index 0000000..19bc808 --- /dev/null +++ b/build_functions/scripts/validate_timed_test_suite.ps1 @@ -0,0 +1,134 @@ +# Copyright (c) Microsoft. All rights reserved. +# Licensed under the MIT license. See LICENSE file in the project root for full license information. + +<# +.SYNOPSIS + Validates that integration test files use TIMED_TEST_SUITE_INITIALIZE/CLEANUP macros. + +.DESCRIPTION + This script checks integration test files (*_int.c) in a given test folder to ensure + they use the timed versions of TEST_SUITE_INITIALIZE and TEST_SUITE_CLEANUP macros. + The timed macros (TIMED_TEST_SUITE_INITIALIZE / TIMED_TEST_SUITE_CLEANUP) wrap the + vanilla versions with a process watchdog that crashes the process and produces a dump + on timeout, allowing dumps to be collected if the test hangs. + +.PARAMETER TestFolder + The path to the test folder to validate. + +.PARAMETER NumExpectedViolations + The number of files expected to have violations. When the actual violation count matches + this value, the script exits with code 0. Default is 0 (no violations expected). + +.EXAMPLE + .\validate_timed_test_suite.ps1 -TestFolder "C:\repo\tests\my_module_int" + + Validates integration test files in the folder and reports files using non-timed macros. + +.NOTES + Returns exit code 0 if violation count matches NumExpectedViolations, 1 otherwise. +#> + +param( + [Parameter(Mandatory=$true)] + [string]$TestFolder, + + [Parameter(Mandatory=$false)] + [int]$NumExpectedViolations = 0 +) + +# Set error action preference +$ErrorActionPreference = "Stop" + +Write-Host "========================================" -ForegroundColor Cyan +Write-Host "Timed Test Suite Validation" -ForegroundColor Cyan +Write-Host "========================================" -ForegroundColor Cyan +Write-Host "Test Folder: $TestFolder" -ForegroundColor White +if ($NumExpectedViolations -gt 0) { + Write-Host "Expected Violations: $NumExpectedViolations" -ForegroundColor White +} +Write-Host "" + +# Get all integration test files in the folder +Write-Host "Searching for integration test files (*_int.c)..." -ForegroundColor White +$allFiles = @(Get-ChildItem -Path $TestFolder -Recurse -Filter "*_int.c" -ErrorAction SilentlyContinue) + +Write-Host "Found $($allFiles.Count) integration test files to check" -ForegroundColor White +Write-Host "" + +# Pattern to match non-timed TEST_SUITE_INITIALIZE/CLEANUP +# Uses negative lookbehind to exclude lines that already have TIMED_ prefix +$initPattern = '(?