ctest: Add test rerun index "(run XX/YY)" to output

This makes the output more user friendly when using CTest's repeat
options (`until-fail`, `until-pass` `after-timeout`).

Closes: #28039
Co-authored-by: Tyler Yankee <tyler.yankee@kitware.com>
This commit is contained in:
Maxime Haselbauer
2026-08-21 09:11:52 -04:00
committed by Tyler Yankee
co-authored by Tyler Yankee
parent c5a5c4a6e2
commit 135c7aa1f1
7 changed files with 40 additions and 33 deletions
+13 -6
View File
@@ -556,13 +556,20 @@ void cmCTestRunTest::StartTest(std::unique_ptr<cmCTestRunTest> runner,
bool cmCTestRunTest::StartTest(size_t completed, size_t total)
{
this->TotalNumberOfTests = total; // save for rerun case
std::string runIterationSuffix{};
if (this->NumberOfRunsTotal > 1) {
runIterationSuffix = " (run " +
std::to_string(1 + this->NumberOfRunsTotal - this->NumberOfRunsLeft) +
"/" + std::to_string(this->NumberOfRunsTotal) + ")";
}
if (!this->CTest->GetTestProgressOutput()) {
cmCTestLog(this->CTest, HANDLER_OUTPUT,
std::setw(2 * getNumWidth(total) + 8)
<< "Start "
<< std::setw(getNumWidth(this->TestHandler->GetMaxIndex()))
<< this->TestProperties->Index << ": "
<< this->TestProperties->Name << std::endl);
cmCTestLog(
this->CTest, HANDLER_OUTPUT,
std::setw(2 * getNumWidth(total) + 8)
<< "Start " << std::setw(getNumWidth(this->TestHandler->GetMaxIndex()))
<< this->TestProperties->Index << ": " << this->TestProperties->Name
<< runIterationSuffix << std::endl);
} else {
std::string testName = this->GetTestPrefix(completed, total) +
this->TestProperties->Name + "\n";
@@ -1,13 +1,13 @@
^Test project .*/Tests/RunCMake/CTestCommandLine/repeat-after-timeout-build
Start 1: initialization
Start 1: initialization \(run 1/3\)
1/4 Test #1: initialization \.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. Passed +[0-9\.]+ sec
Start 2: test1
Start 2: test1 \(run 1/3\)
2/4 Test #2: test1 \.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\*\*\*Timeout +[0-9\.]+ sec
Start 2: test1
Start 2: test1 \(run 2/3\)
Test #2: test1 \.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. Passed +[0-9\.]+ sec
Start 3: hello
Start 3: hello \(run 1/3\)
3/4 Test #3: hello \.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. Passed +[0-9\.]+ sec
Start 4: goodbye
Start 4: goodbye \(run 1/3\)
4/4 Test #4: goodbye \.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. Passed +[0-9\.]+ sec
100% tests passed out of 4
@@ -1,25 +1,25 @@
^Test project .*/Tests/RunCMake/CTestCommandLine/repeat-until-fail-build
Start 1: initialization
Start 1: initialization \(run 1/3\)
Test #1: initialization \.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. Passed +[0-9\.]+ sec
Start 1: initialization
Start 1: initialization \(run 2/3\)
Test #1: initialization \.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. Passed +[0-9\.]+ sec
Start 1: initialization
Start 1: initialization \(run 3/3\)
1/4 Test #1: initialization \.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. Passed +[0-9\.]+ sec
Start 2: test1
Start 2: test1 \(run 1/3\)
Test #2: test1 \.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. Passed +[0-9\.]+ sec
Start 2: test1
Start 2: test1 \(run 2/3\)
Test #2: test1 \.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\*\*\*Failed +[0-9\.]+ sec
Start 3: hello
Start 3: hello \(run 1/3\)
Test #3: hello \.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. Passed +[0-9\.]+ sec
Start 3: hello
Start 3: hello \(run 2/3\)
Test #3: hello \.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. Passed +[0-9\.]+ sec
Start 3: hello
Start 3: hello \(run 3/3\)
3/4 Test #3: hello \.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. Passed +[0-9\.]+ sec
Start 4: goodbye
Start 4: goodbye \(run 1/3\)
Test #4: goodbye \.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. Passed +[0-9\.]+ sec
Start 4: goodbye
Start 4: goodbye \(run 2/3\)
Test #4: goodbye \.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. Passed +[0-9\.]+ sec
Start 4: goodbye
Start 4: goodbye \(run 3/3\)
4/4 Test #4: goodbye \.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. Passed +[0-9\.]+ sec
+
75% tests passed, 1 tests failed out of 4
@@ -1,13 +1,13 @@
^Test project .*/Tests/RunCMake/CTestCommandLine/repeat-until-pass-build
Start 1: initialization
Start 1: initialization \(run 1/3\)
1/4 Test #1: initialization \.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. Passed +[0-9\.]+ sec
Start 2: test1
Start 2: test1 \(run 1/3\)
2/4 Test #2: test1 \.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\*\*\*Failed +[0-9\.]+ sec
Start 2: test1
Start 2: test1 \(run 2/3\)
Test #2: test1 \.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. Passed +[0-9\.]+ sec
Start 3: hello
Start 3: hello \(run 1/3\)
3/4 Test #3: hello \.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. Passed +[0-9\.]+ sec
Start 4: goodbye
Start 4: goodbye \(run 1/3\)
4/4 Test #4: goodbye \.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. Passed +[0-9\.]+ sec
100% tests passed out of 4
@@ -1,8 +1,8 @@
Test project [^
]*/Tests/RunCMake/ctest_test/TestRepeatAfterTimeout-build
Start 1: testRepeat
Start 1: testRepeat \(run 1/3\)
1/1 Test #1: testRepeat \.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\*\*\*Timeout +[0-9\.]+ sec
Start 1: testRepeat
Start 1: testRepeat \(run 2/3\)
Test #1: testRepeat \.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. Passed +[0-9\.]+ sec
+
100% tests passed out of 1
@@ -1,8 +1,8 @@
Test project [^
]*/Tests/RunCMake/ctest_test/TestRepeatUntilFail-build
Start 1: testRepeat
Start 1: testRepeat \(run 1/3\)
Test #1: testRepeat \.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. Passed +[0-9\.]+ sec
Start 1: testRepeat
Start 1: testRepeat \(run 2/3\)
Test #1: testRepeat \.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\*\*\*Failed +[0-9\.]+ sec
+
0% tests passed, 1 tests failed out of 1
@@ -1,8 +1,8 @@
Test project [^
]*/Tests/RunCMake/ctest_test/TestRepeatUntilPass-build
Start 1: testRepeat
Start 1: testRepeat \(run 1/3\)
1/1 Test #1: testRepeat \.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\*\*\*Failed +[0-9\.]+ sec
Start 1: testRepeat
Start 1: testRepeat \(run 2/3\)
Test #1: testRepeat \.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\.\. Passed +[0-9\.]+ sec
+
100% tests passed out of 1