diff options
Diffstat (limited to 'Source/cmCTest.cxx')
-rw-r--r-- | Source/cmCTest.cxx | 80 |
1 files changed, 77 insertions, 3 deletions
diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx index 6639787..908eea1 100644 --- a/Source/cmCTest.cxx +++ b/Source/cmCTest.cxx @@ -24,6 +24,11 @@ #include <time.h> #include <utility> #include <vector> +#if defined(_WIN32) +# include <windows.h> // IWYU pragma: keep +#else +# include <unistd.h> // IWYU pragma: keep +#endif #include "cmAlgorithms.h" #include "cmCTestBuildAndTestHandler.h" @@ -263,6 +268,8 @@ cmCTest::cmCTest() this->Failover = false; this->ForceNewCTestProcess = false; this->TomorrowTag = false; + this->TestProgressOutput = false; + this->FlushTestProgressLine = false; this->Verbose = false; this->Debug = false; @@ -290,10 +297,16 @@ cmCTest::cmCTest() this->OutputTestOutputOnTestFailure = false; this->RepeatTests = 1; // default to run each test once this->RepeatUntilFail = false; - std::string outOnFail; - if (cmSystemTools::GetEnv("CTEST_OUTPUT_ON_FAILURE", outOnFail)) { - this->OutputTestOutputOnTestFailure = !cmSystemTools::IsOff(outOnFail); + + std::string envValue; + if (cmSystemTools::GetEnv("CTEST_OUTPUT_ON_FAILURE", envValue)) { + this->OutputTestOutputOnTestFailure = !cmSystemTools::IsOff(envValue); + } + envValue.clear(); + if (cmSystemTools::GetEnv("CTEST_PROGRESS_OUTPUT", envValue)) { + this->TestProgressOutput = !cmSystemTools::IsOff(envValue); } + this->InitStreams(); this->Parts[PartStart].SetName("Start"); @@ -1875,6 +1888,9 @@ bool cmCTest::HandleCommandLineArguments(size_t& i, if (this->CheckArgument(arg, "-Q", "--quiet")) { this->Quiet = true; } + if (this->CheckArgument(arg, "--progress")) { + this->TestProgressOutput = true; + } if (this->CheckArgument(arg, "-V", "--verbose")) { this->Verbose = true; } @@ -2038,6 +2054,23 @@ bool cmCTest::HandleCommandLineArguments(size_t& i, return true; } +bool cmCTest::ProgressOutputSupportedByConsole() const +{ +#if defined(_WIN32) + // On Windows we need a console buffer. + void* console = GetStdHandle(STD_OUTPUT_HANDLE); + CONSOLE_SCREEN_BUFFER_INFO csbi; + return GetConsoleScreenBufferInfo(console, &csbi); +#else + // On UNIX we need a non-dumb tty. + std::string term_env_variable; + if (cmSystemTools::GetEnv("TERM", term_env_variable)) { + return isatty(1) && term_env_variable != "dumb"; + } +#endif + return false; +} + // handle the -S -SR and -SP arguments void cmCTest::HandleScriptArguments(size_t& i, std::vector<std::string>& args, bool& SRArgumentSpecified) @@ -2192,6 +2225,18 @@ int cmCTest::Run(std::vector<std::string>& args, std::string* output) } } + // TestProgressOutput only supported if console supports it and not logging + // to a file + this->TestProgressOutput = this->TestProgressOutput && + !this->OutputLogFile && this->ProgressOutputSupportedByConsole(); +#ifdef _WIN32 + if (this->TestProgressOutput) { + // Disable output line buffering so we can print content without + // a newline. + std::setvbuf(stdout, nullptr, _IONBF, 0); + } +#endif + // now what should cmake do? if --build-and-test was specified then // we run the build and test handler and return if (cmakeAndTest) { @@ -2761,6 +2806,7 @@ static const char* cmCTestStringLogType[] = { "DEBUG", "OUTPUT", "HANDLER_OUTPUT", "HANDLER_PROGRESS_OUTPUT", + "HANDLER_TEST_PROGRESS_OUTPUT", "HANDLER_VERBOSE_OUTPUT", "WARNING", "ERROR_MESSAGE", @@ -2821,6 +2867,34 @@ void cmCTest::Log(int logType, const char* file, int line, const char* msg, if (!this->Quiet) { std::ostream& out = *this->StreamOut; std::ostream& err = *this->StreamErr; + + if (logType == HANDLER_TEST_PROGRESS_OUTPUT) { + if (this->TestProgressOutput) { + cmCTestLogOutputFileLine(out); + if (this->FlushTestProgressLine) { + printf("\r"); + this->FlushTestProgressLine = false; + out.flush(); + } + + std::string msg_str{ msg }; + auto const lineBreakIt = msg_str.find('\n'); + if (lineBreakIt != std::string::npos) { + this->FlushTestProgressLine = true; + msg_str.erase(std::remove(msg_str.begin(), msg_str.end(), '\n'), + msg_str.end()); + } + + out << msg_str; +#ifndef _WIN32 + printf("\x1B[K"); // move caret to end +#endif + out.flush(); + return; + } + logType = HANDLER_OUTPUT; + } + switch (logType) { case DEBUG: if (this->Debug) { |