mirror of
https://gitlab.kitware.com/cmake/cmake.git
synced 2026-10-04 04:03:22 +03:00
ctest: Honor --interactive-debug-mode in dashboard and script modes
ctest_start() and -D/-M were resetting the mode through SetTestModel, so an explicit --interactive-debug-mode got lost. We now keep the user's value separately and GetInteractiveDebugMode() prefers it. Also made ProcessSteps go through the same getter, so under -T ctest and its tests no longer end up in different modes. Fixes: #28107
This commit is contained in:
1 parent
de8a69ce2d
commit
273ef22e84
5 files changed
+133
-7
No files matched your search
+16
-7
@@ -183,7 +183,9 @@ struct cmCTest::Private
|
||||
|
||||
std::string NotesFiles;
|
||||
|
||||
// Default for the current mode; an explicit user choice takes precedence.
|
||||
bool InteractiveDebugMode = true;
|
||||
cm::optional<bool> InteractiveDebugModeCli;
|
||||
|
||||
bool ShortDateFormat = true;
|
||||
|
||||
@@ -451,7 +453,7 @@ void cmCTest::Initialize(std::string const& binary_dir)
|
||||
this->Impl->Parts[p].SubmitFiles.clear();
|
||||
}
|
||||
|
||||
if (!this->Impl->InteractiveDebugMode) {
|
||||
if (!this->GetInteractiveDebugMode()) {
|
||||
this->BlockTestErrorDiagnostics();
|
||||
} else {
|
||||
cmSystemTools::PutEnv("CTEST_INTERACTIVE_DEBUG_MODE=1");
|
||||
@@ -766,12 +768,18 @@ int cmCTest::ProcessSteps()
|
||||
this->Impl->ExtraVerbose = this->Impl->Verbose;
|
||||
this->Impl->Verbose = true;
|
||||
this->Impl->ProduceXML = true;
|
||||
// Dashboard mode defaults to non-interactive even if no model is set.
|
||||
this->Impl->InteractiveDebugMode = false;
|
||||
|
||||
// Minimal dashboard client script configuration.
|
||||
this->SetCTestConfiguration("BuildDirectory", this->Impl->BinaryDir);
|
||||
|
||||
this->UpdateCTestConfiguration();
|
||||
this->BlockTestErrorDiagnostics();
|
||||
if (!this->GetInteractiveDebugMode()) {
|
||||
this->BlockTestErrorDiagnostics();
|
||||
} else {
|
||||
cmSystemTools::PutEnv("CTEST_INTERACTIVE_DEBUG_MODE=1");
|
||||
}
|
||||
|
||||
if (this->GetCTestConfiguration("TimeOut").empty()) {
|
||||
this->SetCTestConfiguration(
|
||||
@@ -1834,8 +1842,8 @@ bool cmCTest::SetArgsFromPreset(cmCMakePresetsArgs const& args)
|
||||
}
|
||||
|
||||
if (expandedPreset->Execution->InteractiveDebugging) {
|
||||
this->Impl->InteractiveDebugMode =
|
||||
*expandedPreset->Execution->InteractiveDebugging;
|
||||
this->Impl->InteractiveDebugModeCli =
|
||||
expandedPreset->Execution->InteractiveDebugging;
|
||||
}
|
||||
|
||||
if (expandedPreset->Execution->ScheduleRandom.value_or(false)) {
|
||||
@@ -2461,7 +2469,7 @@ int cmCTest::Run(std::vector<std::string> const& args)
|
||||
CommandArgument{ "--max-width", CommandArgument::Values::One, dashW },
|
||||
CommandArgument{ "--interactive-debug-mode", CommandArgument::Values::One,
|
||||
[this](std::string const& idm) -> bool {
|
||||
this->Impl->InteractiveDebugMode = cmIsOn(idm);
|
||||
this->Impl->InteractiveDebugModeCli = cmIsOn(idm);
|
||||
return true;
|
||||
} },
|
||||
CommandArgument{ "--http-header", CommandArgument::Values::One,
|
||||
@@ -2780,7 +2788,7 @@ int cmCTest::ExecuteTests(std::vector<std::string> const& args)
|
||||
this->Impl->Verbose = true;
|
||||
|
||||
cmCTestLog(this, DEBUG, "Here: " << __LINE__ << std::endl);
|
||||
if (!this->Impl->InteractiveDebugMode) {
|
||||
if (!this->GetInteractiveDebugMode()) {
|
||||
this->BlockTestErrorDiagnostics();
|
||||
} else {
|
||||
cmSystemTools::PutEnv("CTEST_INTERACTIVE_DEBUG_MODE=1");
|
||||
@@ -3244,7 +3252,8 @@ bool cmCTest::GetExtraVerbose() const
|
||||
|
||||
bool cmCTest::GetInteractiveDebugMode() const
|
||||
{
|
||||
return this->Impl->InteractiveDebugMode;
|
||||
return this->Impl->InteractiveDebugModeCli.value_or(
|
||||
this->Impl->InteractiveDebugMode);
|
||||
}
|
||||
|
||||
bool cmCTest::GetLabelSummary() const
|
||||
|
||||
@@ -1263,6 +1263,11 @@ set(CTestCommandLine_ARGS
|
||||
if(NOT CMake_TEST_EXTERNAL_CMAKE)
|
||||
list(APPEND CTestCommandLine_ARGS -DTEST_AFFINITY=$<TARGET_FILE:testAffinity>)
|
||||
endif()
|
||||
# Tests inherit ctest's error mode only through a flag of the bundled libuv.
|
||||
if(WIN32 AND NOT CMAKE_USE_SYSTEM_LIBUV)
|
||||
add_executable(testErrorMode testErrorMode.c)
|
||||
list(APPEND CTestCommandLine_ARGS -DTEST_ERROR_MODE=$<TARGET_FILE:testErrorMode>)
|
||||
endif()
|
||||
add_executable(print_stdin print_stdin.c)
|
||||
add_RunCMake_test(CTestCommandLine -DTEST_PRINT_STDIN=$<TARGET_FILE:print_stdin>)
|
||||
add_RunCMake_test(CacheNewline)
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"version": 3,
|
||||
"configurePresets": [
|
||||
{
|
||||
"name": "default",
|
||||
"binaryDir": "${sourceDir}"
|
||||
}
|
||||
],
|
||||
"testPresets": [
|
||||
{
|
||||
"name": "default",
|
||||
"configurePreset": "default",
|
||||
"execution": {
|
||||
"interactiveDebugging": false
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1072,6 +1072,59 @@ block()
|
||||
-T Test)
|
||||
endblock()
|
||||
|
||||
# CTest itself and the tests it runs must agree on the debug mode: tests see
|
||||
# only that mode's environment marker and, on Windows, its error mode.
|
||||
function(run_InteractiveDebugMode case mode)
|
||||
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/InteractiveDebugMode-${case})
|
||||
set(RunCMake_TEST_NO_CLEAN 1)
|
||||
file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
|
||||
file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
|
||||
if(mode STREQUAL "interactive")
|
||||
set(expect_env "CTEST_INTERACTIVE_DEBUG_MODE=1")
|
||||
set(reject_env "DASHBOARD_TEST_FROM_CTEST=")
|
||||
else()
|
||||
set(expect_env "DASHBOARD_TEST_FROM_CTEST=")
|
||||
set(reject_env "CTEST_INTERACTIVE_DEBUG_MODE=")
|
||||
endif()
|
||||
set(tests "
|
||||
add_test(env \"${CMAKE_COMMAND}\" -E environment)
|
||||
set_tests_properties(env PROPERTIES
|
||||
PASS_REGULAR_EXPRESSION \"${expect_env}\"
|
||||
FAIL_REGULAR_EXPRESSION \"${reject_env}\")
|
||||
")
|
||||
if(TEST_ERROR_MODE)
|
||||
string(APPEND tests "add_test(error-mode \"${TEST_ERROR_MODE}\" ${mode})\n")
|
||||
endif()
|
||||
file(WRITE "${RunCMake_TEST_BINARY_DIR}/CTestTestfile.cmake" "${tests}")
|
||||
file(WRITE "${RunCMake_TEST_BINARY_DIR}/DartConfiguration.tcl"
|
||||
"BuildDirectory: ${RunCMake_TEST_BINARY_DIR}\n"
|
||||
"SourceDirectory: ${RunCMake_TEST_BINARY_DIR}\n")
|
||||
file(WRITE "${RunCMake_TEST_BINARY_DIR}/script.cmake" "
|
||||
set(CTEST_SOURCE_DIRECTORY \"${RunCMake_TEST_BINARY_DIR}\")
|
||||
set(CTEST_BINARY_DIRECTORY \"${RunCMake_TEST_BINARY_DIR}\")
|
||||
ctest_start(Experimental)
|
||||
ctest_test(RETURN_VALUE rv)
|
||||
if(rv)
|
||||
message(FATAL_ERROR \"ctest_test failed: \${rv}\")
|
||||
endif()
|
||||
")
|
||||
set(presets "${RunCMake_SOURCE_DIR}/InteractiveDebugMode-${case}-CMakePresets.json.in")
|
||||
if(EXISTS "${presets}")
|
||||
configure_file("${presets}" "${RunCMake_TEST_BINARY_DIR}/CMakePresets.json" @ONLY)
|
||||
endif()
|
||||
# CTest never unsets these, so an outer CTest would leak them into the case.
|
||||
unset(ENV{DASHBOARD_TEST_FROM_CTEST})
|
||||
unset(ENV{DART_TEST_FROM_DART})
|
||||
unset(ENV{CTEST_INTERACTIVE_DEBUG_MODE})
|
||||
run_cmake_command(InteractiveDebugMode-${case} ${CMAKE_CTEST_COMMAND} ${ARGN})
|
||||
endfunction()
|
||||
run_InteractiveDebugMode(Default interactive)
|
||||
run_InteractiveDebugMode(PresetOff non-interactive --preset=default)
|
||||
run_InteractiveDebugMode(Script non-interactive -S script.cmake)
|
||||
run_InteractiveDebugMode(ScriptOn interactive -S script.cmake --interactive-debug-mode 1)
|
||||
run_InteractiveDebugMode(DashT non-interactive -T Test)
|
||||
run_InteractiveDebugMode(OnDashD interactive --interactive-debug-mode 1 -D ExperimentalTest)
|
||||
|
||||
# Test --output-junit
|
||||
function(run_output_junit)
|
||||
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/output-junit)
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1928
|
||||
# pragma warning(disable : 5105) /* macro expansion warning in windows.h */
|
||||
#endif
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Verify that a test process inherited the error mode of its CTest mode. */
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
UINT mode;
|
||||
int expectSuppressed;
|
||||
int suppressed;
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "usage: testErrorMode interactive|non-interactive\n");
|
||||
return 2;
|
||||
}
|
||||
if (strcmp(argv[1], "interactive") == 0) {
|
||||
expectSuppressed = 0;
|
||||
} else if (strcmp(argv[1], "non-interactive") == 0) {
|
||||
expectSuppressed = 1;
|
||||
} else {
|
||||
fprintf(stderr, "unknown mode: %s\n", argv[1]);
|
||||
return 2;
|
||||
}
|
||||
|
||||
/* Older MinGW-w64 headers declare GetErrorMode only for Vista+. */
|
||||
mode = SetErrorMode(0);
|
||||
SetErrorMode(mode);
|
||||
|
||||
suppressed = (mode & SEM_NOGPFAULTERRORBOX) != 0;
|
||||
if (suppressed != expectSuppressed) {
|
||||
fprintf(stderr, "SEM_NOGPFAULTERRORBOX is %s, expected %s\n",
|
||||
suppressed ? "set" : "clear", expectSuppressed ? "set" : "clear");
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Reference in new issue
Block a user