BUG: Capture cout and cerr from internal ctest
When CTest detects that a test is running its own executable it optimizes the test by using an internal instance of cmCTest instead of creating a new process. However, the internal instance was using cout and cerr directly. This redirects the output to a string stream to avoid direct display of the internal test's output.
This commit is contained in:
parent
86aeefc7c9
commit
2703d51b8f
|
@ -258,6 +258,7 @@ cmCTest::cmCTest()
|
||||||
this->OutputLogFileLastTag = -1;
|
this->OutputLogFileLastTag = -1;
|
||||||
this->SuppressUpdatingCTestConfiguration = false;
|
this->SuppressUpdatingCTestConfiguration = false;
|
||||||
this->DartVersion = 1;
|
this->DartVersion = 1;
|
||||||
|
this->InitStreams();
|
||||||
|
|
||||||
int cc;
|
int cc;
|
||||||
for ( cc=0; cc < cmCTest::LAST_TEST; cc ++ )
|
for ( cc=0; cc < cmCTest::LAST_TEST; cc ++ )
|
||||||
|
@ -1136,6 +1137,11 @@ int cmCTest::RunTest(std::vector<const char*> argv,
|
||||||
cmCTest inst;
|
cmCTest inst;
|
||||||
inst.ConfigType = this->ConfigType;
|
inst.ConfigType = this->ConfigType;
|
||||||
inst.TimeOut = timeout;
|
inst.TimeOut = timeout;
|
||||||
|
|
||||||
|
// Capture output of the child ctest.
|
||||||
|
cmOStringStream oss;
|
||||||
|
inst.SetStreams(&oss, &oss);
|
||||||
|
|
||||||
std::vector<std::string> args;
|
std::vector<std::string> args;
|
||||||
for(unsigned int i =0; i < argv.size(); ++i)
|
for(unsigned int i =0; i < argv.size(); ++i)
|
||||||
{
|
{
|
||||||
|
@ -1166,6 +1172,7 @@ int cmCTest::RunTest(std::vector<const char*> argv,
|
||||||
}
|
}
|
||||||
|
|
||||||
*retVal = inst.Run(args, output);
|
*retVal = inst.Run(args, output);
|
||||||
|
*output += oss.str();
|
||||||
if ( log )
|
if ( log )
|
||||||
{
|
{
|
||||||
*log << output->c_str();
|
*log << output->c_str();
|
||||||
|
@ -2602,6 +2609,13 @@ static const char* cmCTestStringLogType[] =
|
||||||
(stream) << std::endl << file << ":" << line << " "; \
|
(stream) << std::endl << file << ":" << line << " "; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cmCTest::InitStreams()
|
||||||
|
{
|
||||||
|
// By default we write output to the process output streams.
|
||||||
|
this->StreamOut = &std::cout;
|
||||||
|
this->StreamErr = &std::cerr;
|
||||||
|
}
|
||||||
|
|
||||||
void cmCTest::Log(int logType, const char* file, int line, const char* msg)
|
void cmCTest::Log(int logType, const char* file, int line, const char* msg)
|
||||||
{
|
{
|
||||||
if ( !msg || !*msg )
|
if ( !msg || !*msg )
|
||||||
|
@ -2640,47 +2654,49 @@ void cmCTest::Log(int logType, const char* file, int line, const char* msg)
|
||||||
}
|
}
|
||||||
if ( !this->Quiet )
|
if ( !this->Quiet )
|
||||||
{
|
{
|
||||||
|
std::ostream& out = *this->StreamOut;
|
||||||
|
std::ostream& err = *this->StreamErr;
|
||||||
switch ( logType )
|
switch ( logType )
|
||||||
{
|
{
|
||||||
case DEBUG:
|
case DEBUG:
|
||||||
if ( this->Debug )
|
if ( this->Debug )
|
||||||
{
|
{
|
||||||
cmCTestLogOutputFileLine(std::cout);
|
cmCTestLogOutputFileLine(out);
|
||||||
std::cout << msg;
|
out << msg;
|
||||||
std::cout.flush();
|
out.flush();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OUTPUT: case HANDLER_OUTPUT:
|
case OUTPUT: case HANDLER_OUTPUT:
|
||||||
if ( this->Debug || this->Verbose )
|
if ( this->Debug || this->Verbose )
|
||||||
{
|
{
|
||||||
cmCTestLogOutputFileLine(std::cout);
|
cmCTestLogOutputFileLine(out);
|
||||||
std::cout << msg;
|
out << msg;
|
||||||
std::cout.flush();
|
out.flush();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case HANDLER_VERBOSE_OUTPUT:
|
case HANDLER_VERBOSE_OUTPUT:
|
||||||
if ( this->Debug || this->ExtraVerbose )
|
if ( this->Debug || this->ExtraVerbose )
|
||||||
{
|
{
|
||||||
cmCTestLogOutputFileLine(std::cout);
|
cmCTestLogOutputFileLine(out);
|
||||||
std::cout << msg;
|
out << msg;
|
||||||
std::cout.flush();
|
out.flush();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case WARNING:
|
case WARNING:
|
||||||
cmCTestLogOutputFileLine(std::cerr);
|
cmCTestLogOutputFileLine(err);
|
||||||
std::cerr << msg;
|
err << msg;
|
||||||
std::cerr.flush();
|
err.flush();
|
||||||
break;
|
break;
|
||||||
case ERROR_MESSAGE:
|
case ERROR_MESSAGE:
|
||||||
cmCTestLogOutputFileLine(std::cerr);
|
cmCTestLogOutputFileLine(err);
|
||||||
std::cerr << msg;
|
err << msg;
|
||||||
std::cerr.flush();
|
err.flush();
|
||||||
cmSystemTools::SetErrorOccured();
|
cmSystemTools::SetErrorOccured();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
cmCTestLogOutputFileLine(std::cout);
|
cmCTestLogOutputFileLine(out);
|
||||||
std::cout << msg;
|
out << msg;
|
||||||
std::cout.flush();
|
out.flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -331,6 +331,10 @@ public:
|
||||||
|
|
||||||
bool GetVerbose() { return this->Verbose;}
|
bool GetVerbose() { return this->Verbose;}
|
||||||
bool GetExtraVerbose() { return this->ExtraVerbose;}
|
bool GetExtraVerbose() { return this->ExtraVerbose;}
|
||||||
|
|
||||||
|
/** Direct process output to given streams. */
|
||||||
|
void SetStreams(std::ostream* out, std::ostream* err)
|
||||||
|
{ this->StreamOut = out; this->StreamErr = err; }
|
||||||
private:
|
private:
|
||||||
std::string ConfigType;
|
std::string ConfigType;
|
||||||
bool Verbose;
|
bool Verbose;
|
||||||
|
@ -402,6 +406,10 @@ private:
|
||||||
|
|
||||||
bool CompressXMLFiles;
|
bool CompressXMLFiles;
|
||||||
|
|
||||||
|
void InitStreams();
|
||||||
|
std::ostream* StreamOut;
|
||||||
|
std::ostream* StreamErr;
|
||||||
|
|
||||||
void BlockTestErrorDiagnostics();
|
void BlockTestErrorDiagnostics();
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue