Commit d4adde13 authored by Zach's avatar Zach
Browse files

Allowed tests to pull more than one line of output in their quantum. Fixed...

Allowed tests to pull more than one line of output in their quantum.  Fixed uninitialized variables in the case that the test process could not start.
parent f686dbec
......@@ -100,7 +100,8 @@ void cmCTestMultiProcessHandler::StartTestProcess(int test)
}
else
{
testRun->EndTest(this->Completed, this->Total);
this->Completed++;
testRun->EndTest(this->Completed, this->Total, false);
}
}
......@@ -209,7 +210,7 @@ bool cmCTestMultiProcessHandler::CheckOutput()
cmCTestRunTest* p = *i;
int test = p->GetIndex();
if(p->EndTest(this->Completed, this->Total))
if(p->EndTest(this->Completed, this->Total, true))
{
this->Passed->push_back(p->GetTestProperties()->Name);
}
......
......@@ -38,25 +38,36 @@ bool cmCTestRunTest::IsRunning()
void cmCTestRunTest::CheckOutput()
{
std::string out, err;
int pipe = this->TestProcess->CheckOutput(.1, out, err);
if(pipe == cmsysProcess_Pipe_STDOUT)
int pipe = this->TestProcess->CheckOutput(.1);
//start our timeout for reading the process output
double clock_start = cmSystemTools::GetTime();
while(this->TestProcess->GetNextOutputLine(out, err))
{
cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
this->GetIndex() << ": " << out << std::endl);
this->ProcessOutput += out;
this->ProcessOutput += "\n";
}
else if(pipe == cmsysProcess_Pipe_STDERR)
{
cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
this->GetIndex() << ": " << err << std::endl);
this->ProcessOutput += err;
this->ProcessOutput += "\n";
if(pipe == cmsysProcess_Pipe_STDOUT)
{
cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
this->GetIndex() << ": " << out << std::endl);
this->ProcessOutput += out;
this->ProcessOutput += "\n";
}
else if(pipe == cmsysProcess_Pipe_STDERR)
{
cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
this->GetIndex() << ": " << err << std::endl);
this->ProcessOutput += err;
this->ProcessOutput += "\n";
}
//timeout while reading process output (could denote infinite output)
if(cmSystemTools::GetTime() - clock_start > .1)
{
break;
}
}
}
//---------------------------------------------------------
bool cmCTestRunTest::EndTest(size_t completed, size_t total)
bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started)
{
//restore the old environment
if (this->ModifyEnv)
......@@ -240,12 +251,14 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total)
<< "----------------------------------------------------------"
<< std::endl << std::endl;
}
this->TestResult.Output = this->ProcessOutput;
this->TestResult.ReturnValue = this->TestProcess->GetExitValue();
this->TestResult.CompletionStatus = "Completed";
this->TestResult.ExecutionTime = this->TestProcess->GetTotalTime();
this->TestHandler->TestResults.push_back( this->TestResult );
if(started)
{
this->TestResult.Output = this->ProcessOutput;
this->TestResult.ReturnValue = this->TestProcess->GetExitValue();
this->TestResult.CompletionStatus = "Completed";
this->TestResult.ExecutionTime = this->TestProcess->GetTotalTime();
this->TestHandler->TestResults.push_back( this->TestResult );
}
this->MemCheckPostProcess();
delete this->TestProcess;
......@@ -290,6 +303,7 @@ bool cmCTestRunTest::StartTest()
this->TestResult.Properties = this->TestProperties;
this->TestResult.ExecutionTime = 0;
this->TestResult.ReturnValue = -1;
this->TestResult.CompletionStatus = "Not Run";
this->TestResult.Status = cmCTestTestHandler::NOT_RUN;
this->TestResult.TestCount = this->TestProperties->Index;
this->TestResult.Name = this->TestProperties->Name;
......
......@@ -56,7 +56,7 @@ public:
//launch the test process, return whether it started correctly
bool StartTest();
//capture and report the test results
bool EndTest(size_t completed, size_t total);
bool EndTest(size_t completed, size_t total, bool started);
//Called by ctest -N to log the command string
void ComputeArguments();
private:
......
......@@ -68,72 +68,80 @@ bool cmProcess::StartProcess()
return (cmsysProcess_GetState(this->Process)
== cmsysProcess_State_Executing);
}
// return true if there is a new line of data
// return false if there is no new data
int cmProcess::CheckOutput(double timeout,
std::string& stdOutLine,
bool cmProcess::GetNextOutputLine(std::string& stdOutLine,
std::string& stdErrLine)
{
if(this->StdErrorBuffer.empty() && this->StdOutBuffer.empty())
{
return false;
}
stdOutLine = "";
stdErrLine = "";
std::vector<char>::iterator outiter =
this->StdOutBuffer.begin();
std::vector<char>::iterator erriter =
this->StdErrorBuffer.begin();
while(1)
// Check for a newline in stdout.
for(;outiter != this->StdOutBuffer.end(); ++outiter)
{
// Check for a newline in stdout.
for(;outiter != this->StdOutBuffer.end(); ++outiter)
if((*outiter == '\r') && ((outiter+1) == this->StdOutBuffer.end()))
{
break;
}
else if(*outiter == '\n' || *outiter == '\0')
{
if((*outiter == '\r') && ((outiter+1) == this->StdOutBuffer.end()))
int length = outiter-this->StdOutBuffer.begin();
if(length > 1 && *(outiter-1) == '\r')
{
break;
--length;
}
else if(*outiter == '\n' || *outiter == '\0')
if(length > 0)
{
int length = outiter-this->StdOutBuffer.begin();
if(length > 1 && *(outiter-1) == '\r')
{
--length;
}
if(length > 0)
{
stdOutLine.append(&this->StdOutBuffer[0], length);
}
this->StdOutBuffer.erase(this->StdOutBuffer.begin(), outiter+1);
this->LastOutputPipe = cmsysProcess_Pipe_STDOUT;
return this->LastOutputPipe;;
stdOutLine.append(&this->StdOutBuffer[0], length);
}
this->StdOutBuffer.erase(this->StdOutBuffer.begin(), outiter+1);
this->LastOutputPipe = cmsysProcess_Pipe_STDOUT;
return true;
}
}
// Check for a newline in stderr.
for(;erriter != this->StdErrorBuffer.end(); ++erriter)
// Check for a newline in stderr.
for(;erriter != this->StdErrorBuffer.end(); ++erriter)
{
if((*erriter == '\r') && ((erriter+1) == this->StdErrorBuffer.end()))
{
if((*erriter == '\r') && ((erriter+1) == this->StdErrorBuffer.end()))
break;
}
else if(*erriter == '\n' || *erriter == '\0')
{
int length = erriter-this->StdErrorBuffer.begin();
if(length > 1 && *(erriter-1) == '\r')
{
break;
--length;
}
else if(*erriter == '\n' || *erriter == '\0')
if(length > 0)
{
int length = erriter-this->StdErrorBuffer.begin();
if(length > 1 && *(erriter-1) == '\r')
{
--length;
}
if(length > 0)
{
stdErrLine.append(&this->StdErrorBuffer[0], length);
}
this->StdErrorBuffer.erase(this->StdErrorBuffer.begin(), erriter+1);
this->LastOutputPipe = cmsysProcess_Pipe_STDERR;
return this->LastOutputPipe;
stdErrLine.append(&this->StdErrorBuffer[0], length);
}
this->StdErrorBuffer.erase(this->StdErrorBuffer.begin(), erriter+1);
this->LastOutputPipe = cmsysProcess_Pipe_STDERR;
return true;
}
}
//If we get here, we have stuff waiting in the buffers, but no newline
return false;
}
// return true if there is a new line of data
// return false if there is no new data
int cmProcess::CheckOutput(double timeout)
{
// Wait for data from the process.
int length;
char* data;
// No newlines found. Wait for more data from the process.
int length;
char* data;
while(1)
{
int pipe = cmsysProcess_WaitForData(this->Process, &data,
&length, &timeout);
if(pipe == cmsysProcess_Pipe_Timeout)
......@@ -147,7 +155,6 @@ int cmProcess::CheckOutput(double timeout,
// Append to the stdout buffer.
std::vector<char>::size_type size = this->StdOutBuffer.size();
this->StdOutBuffer.insert(this->StdOutBuffer.end(), data, data+length);
outiter = this->StdOutBuffer.begin()+size;
}
else if(pipe == cmsysProcess_Pipe_STDERR)
{
......@@ -155,26 +162,17 @@ int cmProcess::CheckOutput(double timeout,
std::vector<char>::size_type size = this->StdErrorBuffer.size();
this->StdErrorBuffer.insert(this->StdErrorBuffer.end(),
data, data+length);
erriter = this->StdErrorBuffer.begin()+size;
}
else if(pipe == cmsysProcess_Pipe_None)
{
// Both stdout and stderr pipes have broken. Return leftover data.
if(!this->StdOutBuffer.empty())
{
stdOutLine.append(&this->StdOutBuffer[0],
outiter-this->StdOutBuffer.begin());
this->StdOutBuffer.erase(this->StdOutBuffer.begin(),
this->StdOutBuffer.end());
this->LastOutputPipe = cmsysProcess_Pipe_STDOUT;
return this->LastOutputPipe;
}
else if(!this->StdErrorBuffer.empty())
{
stdErrLine.append(&this->StdErrorBuffer[0],
erriter-this->StdErrorBuffer.begin());
this->StdErrorBuffer.erase(this->StdErrorBuffer.begin(),
this->StdErrorBuffer.end());
this->LastOutputPipe = cmsysProcess_Pipe_STDERR;
return this->LastOutputPipe;
}
......@@ -187,7 +185,6 @@ int cmProcess::CheckOutput(double timeout,
}
}
// return the process status
int cmProcess::GetProcessStatus()
{
......
......@@ -41,9 +41,7 @@ public:
bool StartProcess();
// return process state
int CheckOutput(double timeout,
std::string& stdOutLine,
std::string& stdErrLine);
int CheckOutput(double timeout);
// return the process status
int GetProcessStatus();
// return true if the process is running
......@@ -54,6 +52,7 @@ public:
void SetId(int id) { this->Id = id;}
int GetExitValue() { return this->ExitValue;}
double GetTotalTime() { return this->TotalTime;}
bool GetNextOutputLine(std::string& stdOutLine, std::string& stdErrLine);
private:
int LastOutputPipe;
double Timeout;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment