diff options
author | Frank Winklmeier <frank.winklmeier@cern.ch> | 2022-03-07 08:28:55 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2022-03-08 13:18:02 (GMT) |
commit | 140704d443e73c2dc74ac8192a109ae0c21e834a (patch) | |
tree | 7781fb36c21aa925d0442daf27ec5344d89e76f9 /Source/CTest | |
parent | 359e5b17d8edd092a1e500698af7968f96fe1d8d (diff) | |
download | CMake-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.cxx | 3 | ||||
-rw-r--r-- | Source/CTest/cmCTestRunTest.cxx | 3 | ||||
-rw-r--r-- | Source/CTest/cmCTestTestHandler.cxx | 57 | ||||
-rw-r--r-- | Source/CTest/cmCTestTestHandler.h | 11 | ||||
-rw-r--r-- | Source/CTest/cmCTestTypes.h | 16 |
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 +}; +} |