summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorAndy Cedilnik <andy.cedilnik@kitware.com>2003-08-13 22:17:11 (GMT)
committerAndy Cedilnik <andy.cedilnik@kitware.com>2003-08-13 22:17:11 (GMT)
commitcbeeaa71880c565226efeab605e0492eb1806e66 (patch)
tree03cb966235bc2e2380ccf4361e28b76f2e40b4ff /Source
parentbeda09a96b2139a5e22f7f78c4cdff7783669d99 (diff)
downloadCMake-cbeeaa71880c565226efeab605e0492eb1806e66.zip
CMake-cbeeaa71880c565226efeab605e0492eb1806e66.tar.gz
CMake-cbeeaa71880c565226efeab605e0492eb1806e66.tar.bz2
ENH: Better error reporting
Diffstat (limited to 'Source')
-rw-r--r--Source/cmCTest.cxx172
-rw-r--r--Source/cmCTest.h15
2 files changed, 155 insertions, 32 deletions
diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx
index 52e75d3..f2fcd61 100644
--- a/Source/cmCTest.cxx
+++ b/Source/cmCTest.cxx
@@ -1685,6 +1685,7 @@ void cmCTest::ProcessDirectory(std::vector<std::string> &passed,
}
cmCTestTestResult cres;
+ cres.m_Status = cmCTest::NOT_RUN;
if (firstTest)
{
@@ -1737,11 +1738,10 @@ void cmCTest::ProcessDirectory(std::vector<std::string> &passed,
{
std::cout << std::endl << "Test command: " << testCommand << std::endl;
}
- bool res = true;
+ int res = 0;
if ( !m_ShowOnly )
{
- res = cmSystemTools::RunSingleCommand(testCommand.c_str(), &output,
- &retVal, 0, false, m_TimeOut);
+ res = this->RunTest(testCommand.c_str(), &output, &retVal);
}
clock_finish = cmSystemTools::GetTime();
@@ -1750,41 +1750,63 @@ void cmCTest::ProcessDirectory(std::vector<std::string> &passed,
if ( !m_ShowOnly )
{
- if (!res || retVal != 0)
+ if (res == cmsysProcess_State_Exited && retVal )
{
- fprintf(stderr,"***Failed\n");
- if (output != "")
+ fprintf(stderr," Passed\n");
+ passed.push_back(args[0].Value);
+ }
+ else
+ {
+ if ( res == cmsysProcess_State_Expired )
{
- if (dartStuff.find(output.c_str()))
- {
- std::string dartString = dartStuff.match(1);
- cmSystemTools::ReplaceString(output, dartString.c_str(),"");
- cres.m_RegressionImages = this->GenerateRegressionImages(dartString);
- }
- if (output != "" && m_Verbose)
+ fprintf(stderr,"***Timeout\n");
+ cres.m_Status = cmCTest::TIMEOUT;
+ }
+ else if ( res == cmsysProcess_State_Exception )
+ {
+ fprintf(stderr,"***Exception: ");
+ switch ( retVal )
{
- std::cerr << output.c_str() << "\n";
+ case cmsysProcess_Exception_Fault:
+ fprintf(stderr,"SegFault");
+ cres.m_Status = cmCTest::SEGFAULT;
+ break;
+ case cmsysProcess_Exception_Illegal:
+ fprintf(stderr,"SegFault");
+ cres.m_Status = cmCTest::ILLEGAL;
+ break;
+ case cmsysProcess_Exception_Interrupt:
+ fprintf(stderr,"SegFault");
+ cres.m_Status = cmCTest::INTERRUPT;
+ break;
+ case cmsysProcess_Exception_Numerical:
+ fprintf(stderr,"SegFault");
+ cres.m_Status = cmCTest::NUMERICAL;
+ break;
+ default:
+ fprintf(stderr,"Other");
+ cres.m_Status = cmCTest::OTHER_FAULT;
}
}
+ else if ( res == cmsysProcess_State_Error )
+ {
+ fprintf(stderr,"***Bad command\n");
+ cres.m_Status = cmCTest::BAD_COMMAND;
+ }
+ else
+ {
+ fprintf(stderr,"***Failed\n");
+ }
failed.push_back(args[0].Value);
}
- else
+ if (output != "")
{
- fprintf(stderr," Passed\n");
- if (output != "")
+ if (dartStuff.find(output.c_str()))
{
- if (dartStuff.find(output.c_str()))
- {
- std::string dartString = dartStuff.match(1);
- cmSystemTools::ReplaceString(output, dartString.c_str(),"");
- cres.m_RegressionImages = this->GenerateRegressionImages(dartString);
- }
- if (output != "" && m_Verbose)
- {
- std::cerr << output.c_str() << "\n";
- }
+ std::string dartString = dartStuff.match(1);
+ cmSystemTools::ReplaceString(output, dartString.c_str(),"");
+ cres.m_RegressionImages = this->GenerateRegressionImages(dartString);
}
- passed.push_back(args[0].Value);
}
}
cres.m_Output = output;
@@ -2018,7 +2040,7 @@ void cmCTest::GenerateDartTestOutput(std::ostream& os)
for ( cc = 0; cc < m_TestResults.size(); cc ++ )
{
cmCTestTestResult *result = &m_TestResults[cc];
- os << "\t<Test Status=\"" << (result->m_ReturnValue?"failed":"passed")
+ os << "\t<Test Status=\"" << (result->m_Status==cmCTest::COMPLETED?"passed":"failed")
<< "\">\n"
<< "\t\t<Name>" << this->MakeXMLSafe(result->m_Name) << "</Name>\n"
<< "\t\t<Path>" << this->MakeXMLSafe(result->m_Path) << "</Path>\n"
@@ -2028,14 +2050,14 @@ void cmCTest::GenerateDartTestOutput(std::ostream& os)
<< this->MakeXMLSafe(result->m_FullCommandLine)
<< "</FullCommandLine>\n"
<< "\t\t<Results>" << std::endl;
- if ( result->m_ReturnValue )
+ if ( result->m_Status != cmCTest::COMPLETED || result->m_ReturnValue )
{
os << "\t\t\t<NamedMeasurement type=\"text/string\" name=\"Exit Code\"><Value>"
- << "CHILDSTATUS" << "</Value></NamedMeasurement>\n"
+ << this->GetTestStatus(result->m_Status) << "</Value></NamedMeasurement>\n"
<< "\t\t\t<NamedMeasurement type=\"text/string\" name=\"Exit Value\"><Value>"
<< result->m_ReturnValue << "</Value></NamedMeasurement>" << std::endl;
- os << result->m_RegressionImages;
}
+ os << result->m_RegressionImages;
os << "\t\t\t<NamedMeasurement type=\"numeric/double\" "
<< "name=\"Execution Time\"><Value>"
<< result->m_ExecutionTime << "</Value></NamedMeasurement>\n"
@@ -2354,3 +2376,89 @@ bool cmCTest::RunMakeCommand(const char* command, std::string* output,
return result;
}
+int cmCTest::RunTest( const char* command, std::string* output, int *retVal)
+{
+ std::vector<cmStdString> args = cmSystemTools::ParseArguments(command);
+
+ if(args.size() < 1)
+ {
+ return false;
+ }
+
+ std::vector<const char*> argv;
+ for(std::vector<cmStdString>::const_iterator a = args.begin();
+ a != args.end(); ++a)
+ {
+ argv.push_back(a->c_str());
+ }
+ argv.push_back(0);
+
+ if ( output )
+ {
+ *output = "";
+ }
+
+ cmsysProcess* cp = cmsysProcess_New();
+ cmsysProcess_SetCommand(cp, &*argv.begin());
+ if(cmSystemTools::GetRunCommandHideConsole())
+ {
+ cmsysProcess_SetOption(cp, cmsysProcess_Option_HideWindow, 1);
+ }
+ cmsysProcess_SetTimeout(cp, m_TimeOut);
+ cmsysProcess_Execute(cp);
+
+ char* data;
+ int length;
+ while(cmsysProcess_WaitForData(cp, (cmsysProcess_Pipe_STDOUT |
+ cmsysProcess_Pipe_STDERR),
+ &data, &length, 0))
+ {
+ if ( output )
+ {
+ output->append(data, length);
+ }
+ }
+
+ cmsysProcess_WaitForExit(cp, 0);
+
+ int result = cmsysProcess_GetState(cp);
+
+ if(result == cmsysProcess_State_Exited)
+ {
+ *retVal = cmsysProcess_GetExitValue(cp);
+ }
+ else if(result == cmsysProcess_State_Exception)
+ {
+ *retVal = cmsysProcess_GetExitException(cp);
+ }
+ else if(result == cmsysProcess_State_Error)
+ {
+ *output += "\n*** ERROR executing: ";
+ *output += cmsysProcess_GetErrorString(cp);
+ }
+
+ cmsysProcess_Delete(cp);
+
+ return result;
+}
+
+const char* cmCTest::GetTestStatus(int status)
+{
+ static const char statuses[][100] = {
+ "Not Run",
+ "Timeout",
+ "SEGFAULT",
+ "ILLEGAL",
+ "INTERRUPT",
+ "NUMERICAL",
+ "OTHER_FAULT",
+ "BAD_COMMAND",
+ "Completed"
+ };
+
+ if ( status < cmCTest::NOT_RUN || status > cmCTest::COMPLETED )
+ {
+ return "No Status";
+ }
+ return statuses[status];
+}
diff --git a/Source/cmCTest.h b/Source/cmCTest.h
index fe26f5b..78f5e5e 100644
--- a/Source/cmCTest.h
+++ b/Source/cmCTest.h
@@ -141,6 +141,18 @@ private:
LAST_TEST = 10
};
+ enum { // Program statuses
+ NOT_RUN = 0,
+ TIMEOUT,
+ SEGFAULT,
+ ILLEGAL,
+ INTERRUPT,
+ NUMERICAL,
+ OTHER_FAULT,
+ BAD_COMMAND,
+ COMPLETED
+ };
+
struct cmCTestTestResult
{
std::string m_Name;
@@ -148,6 +160,7 @@ private:
std::string m_FullCommandLine;
double m_ExecutionTime;
int m_ReturnValue;
+ int m_Status;
std::string m_CompletionStatus;
std::string m_Output;
std::string m_RegressionImages;
@@ -227,8 +240,10 @@ private:
bool RunMakeCommand(const char* command, std::string* output,
int* retVal, const char* dir, bool verbose, int timeout, std::ofstream& ofs);
+ int RunTest( const char* command, std::string* output, int *retVal);
std::string GenerateRegressionImages(const std::string& xml);
+ const char* GetTestStatus(int status);
};
#endif