summaryrefslogtreecommitdiffstats
path: root/Source/CTest
diff options
context:
space:
mode:
authorFrank Winklmeier <frank.winklmeier@cern.ch>2022-03-07 08:28:55 (GMT)
committerBrad King <brad.king@kitware.com>2022-03-08 13:18:02 (GMT)
commit140704d443e73c2dc74ac8192a109ae0c21e834a (patch)
tree7781fb36c21aa925d0442daf27ec5344d89e76f9 /Source/CTest
parent359e5b17d8edd092a1e500698af7968f96fe1d8d (diff)
downloadCMake-140704d443e73c2dc74ac8192a109ae0c21e834a.zip
CMake-140704d443e73c2dc74ac8192a109ae0c21e834a.tar.gz
CMake-140704d443e73c2dc74ac8192a109ae0c21e834a.tar.bz2
ctest: add option for output truncation
Add `--test-output-truncation` to `ctest`. This option can be used to customize which part of the test output is being truncated. Currently supported values are `tail`, `middle` and `head`. Also add equivalent `CTEST_CUSTOM_TEST_OUTPUT_TRUNCATION` variable. Fixes: #23206
Diffstat (limited to 'Source/CTest')
-rw-r--r--Source/CTest/cmCTestMemCheckHandler.cxx3
-rw-r--r--Source/CTest/cmCTestRunTest.cxx3
-rw-r--r--Source/CTest/cmCTestTestHandler.cxx57
-rw-r--r--Source/CTest/cmCTestTestHandler.h11
-rw-r--r--Source/CTest/cmCTestTypes.h16
5 files changed, 73 insertions, 17 deletions
diff --git a/Source/CTest/cmCTestMemCheckHandler.cxx b/Source/CTest/cmCTestMemCheckHandler.cxx
index 6bb8e79..2d8276a 100644
--- a/Source/CTest/cmCTestMemCheckHandler.cxx
+++ b/Source/CTest/cmCTestMemCheckHandler.cxx
@@ -371,7 +371,8 @@ void cmCTestMemCheckHandler::GenerateCTestXML(cmXMLWriter& xml)
}
this->CleanTestOutput(
memcheckstr,
- static_cast<size_t>(this->CustomMaximumFailedTestOutputSize));
+ static_cast<size_t>(this->CustomMaximumFailedTestOutputSize),
+ this->TestOutputTruncation);
this->WriteTestResultHeader(xml, result);
xml.StartElement("Results");
int memoryErrors = 0;
diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx
index 6cd3b09..f594300 100644
--- a/Source/CTest/cmCTestRunTest.cxx
+++ b/Source/CTest/cmCTestRunTest.cxx
@@ -277,7 +277,8 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started)
static_cast<size_t>(
this->TestResult.Status == cmCTestTestHandler::COMPLETED
? this->TestHandler->CustomMaximumPassedTestOutputSize
- : this->TestHandler->CustomMaximumFailedTestOutputSize));
+ : this->TestHandler->CustomMaximumFailedTestOutputSize),
+ this->TestHandler->TestOutputTruncation);
}
this->TestResult.Reason = reason;
if (this->TestHandler->LogFile) {
diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx
index 958c51c..a794e3d 100644
--- a/Source/CTest/cmCTestTestHandler.cxx
+++ b/Source/CTest/cmCTestTestHandler.cxx
@@ -281,6 +281,7 @@ cmCTestTestHandler::cmCTestTestHandler()
this->CustomMaximumPassedTestOutputSize = 1 * 1024;
this->CustomMaximumFailedTestOutputSize = 300 * 1024;
+ this->TestOutputTruncation = cmCTestTypes::TruncationMode::Tail;
this->MemCheck = false;
@@ -325,6 +326,7 @@ void cmCTestTestHandler::Initialize()
this->CustomPostTest.clear();
this->CustomMaximumPassedTestOutputSize = 1 * 1024;
this->CustomMaximumFailedTestOutputSize = 300 * 1024;
+ this->TestOutputTruncation = cmCTestTypes::TruncationMode::Tail;
this->TestsToRun.clear();
@@ -358,6 +360,11 @@ void cmCTestTestHandler::PopulateCustomVectors(cmMakefile* mf)
this->CTest->PopulateCustomInteger(
mf, "CTEST_CUSTOM_MAXIMUM_FAILED_TEST_OUTPUT_SIZE",
this->CustomMaximumFailedTestOutputSize);
+
+ cmValue dval = mf->GetDefinition("CTEST_CUSTOM_TEST_OUTPUT_TRUNCATION");
+ if (dval) {
+ this->SetTestOutputTruncation(dval);
+ }
}
int cmCTestTestHandler::PreProcessHandler()
@@ -2076,6 +2083,20 @@ void cmCTestTestHandler::SetExcludeRegExp(const std::string& arg)
this->ExcludeRegExp = arg;
}
+bool cmCTestTestHandler::SetTestOutputTruncation(const std::string& mode)
+{
+ if (mode == "tail") {
+ this->TestOutputTruncation = cmCTestTypes::TruncationMode::Tail;
+ } else if (mode == "middle") {
+ this->TestOutputTruncation = cmCTestTypes::TruncationMode::Middle;
+ } else if (mode == "head") {
+ this->TestOutputTruncation = cmCTestTypes::TruncationMode::Head;
+ } else {
+ return false;
+ }
+ return true;
+}
+
void cmCTestTestHandler::SetTestsToRunInformation(cmValue in)
{
if (!in) {
@@ -2094,7 +2115,8 @@ void cmCTestTestHandler::SetTestsToRunInformation(cmValue in)
}
}
-void cmCTestTestHandler::CleanTestOutput(std::string& output, size_t length)
+void cmCTestTestHandler::CleanTestOutput(std::string& output, size_t length,
+ cmCTestTypes::TruncationMode truncate)
{
if (!length || length >= output.size() ||
output.find("CTEST_FULL_OUTPUT") != std::string::npos) {
@@ -2122,20 +2144,29 @@ void cmCTestTestHandler::CleanTestOutput(std::string& output, size_t length)
return current;
};
- // Truncate at given length respecting UTF-8 words
+ // Truncation message.
+ const std::string msg =
+ "\n[This part of the test output was removed since it "
+ "exceeds the threshold of " +
+ std::to_string(length) + " bytes.]\n";
+
char const* const begin = output.c_str();
char const* const end = begin + output.size();
- char const* current = utf8_advance(begin, end, length);
- output.erase(current - begin);
-
- // Append truncation message.
- std::ostringstream msg;
- msg << "...\n"
- "The rest of the test output was removed since it exceeds the "
- "threshold "
- "of "
- << length << " bytes.\n";
- output += msg.str();
+
+ // Erase head, middle or tail of output.
+ if (truncate == cmCTestTypes::TruncationMode::Head) {
+ char const* current = utf8_advance(begin, end, output.size() - length);
+ output.erase(0, current - begin);
+ output.insert(0, msg + "...");
+ } else if (truncate == cmCTestTypes::TruncationMode::Middle) {
+ char const* current = utf8_advance(begin, end, length / 2);
+ output.erase(current - begin, output.size() - length);
+ output.insert(current - begin, "..." + msg + "...");
+ } else { // default or "tail"
+ char const* current = utf8_advance(begin, end, length);
+ output.erase(current - begin);
+ output += ("..." + msg);
+ }
}
bool cmCTestTestHandler::SetTestsProperties(
diff --git a/Source/CTest/cmCTestTestHandler.h b/Source/CTest/cmCTestTestHandler.h
index 135e764..d0049da 100644
--- a/Source/CTest/cmCTestTestHandler.h
+++ b/Source/CTest/cmCTestTestHandler.h
@@ -19,6 +19,7 @@
#include "cmCTest.h"
#include "cmCTestGenericHandler.h"
#include "cmCTestResourceSpec.h"
+#include "cmCTestTypes.h"
#include "cmDuration.h"
#include "cmListFileCache.h"
#include "cmValue.h"
@@ -32,6 +33,7 @@ class cmXMLWriter;
*/
class cmCTestTestHandler : public cmCTestGenericHandler
{
+ friend class cmCTest;
friend class cmCTestRunTest;
friend class cmCTestMultiProcessHandler;
@@ -80,6 +82,9 @@ public:
this->CustomMaximumFailedTestOutputSize = n;
}
+ //! Set test output truncation mode. Return false if unknown mode.
+ bool SetTestOutputTruncation(const std::string& mode);
+
//! pass the -I argument down
void SetTestsToRunInformation(cmValue);
@@ -242,8 +247,9 @@ protected:
void AttachFile(cmXMLWriter& xml, std::string const& file,
std::string const& name);
- //! Clean test output to specified length
- void CleanTestOutput(std::string& output, size_t length);
+ //! Clean test output to specified length and truncation mode
+ void CleanTestOutput(std::string& output, size_t length,
+ cmCTestTypes::TruncationMode truncate);
cmDuration ElapsedTestingTime;
@@ -258,6 +264,7 @@ protected:
bool MemCheck;
int CustomMaximumPassedTestOutputSize;
int CustomMaximumFailedTestOutputSize;
+ cmCTestTypes::TruncationMode TestOutputTruncation;
int MaxIndex;
public:
diff --git a/Source/CTest/cmCTestTypes.h b/Source/CTest/cmCTestTypes.h
new file mode 100644
index 0000000..843d27a
--- /dev/null
+++ b/Source/CTest/cmCTestTypes.h
@@ -0,0 +1,16 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+#pragma once
+
+#include "cmConfigure.h" // IWYU pragma: keep
+
+namespace cmCTestTypes {
+
+enum class TruncationMode
+{ // Test output truncation mode
+ Tail,
+ Middle,
+ Head
+};
+}