Commit 1b578d31 authored by Andy Cedilnik's avatar Andy Cedilnik
Browse files

ENH: Several improvements with the way things are handled. Also, support multiple submited files

parent 5c68b61a
......@@ -212,6 +212,7 @@ SET(CMTEST_SRCS cmCTest.cxx
CTest/cmCTestCoverageHandler.cxx
CTest/cmCTestEmptyBinaryDirectoryCommand.cxx
CTest/cmCTestGenericHandler.cxx
CTest/cmCTestHandlerCommand.cxx
CTest/cmCTestMemCheckCommand.cxx
CTest/cmCTestMemCheckHandler.cxx
CTest/cmCTestRunScriptCommand.cxx
......
......@@ -34,6 +34,7 @@ cmCTestBuildAndTestHandler::cmCTestBuildAndTestHandler()
//----------------------------------------------------------------------
void cmCTestBuildAndTestHandler::Initialize()
{
this->Superclass::Initialize();
}
//----------------------------------------------------------------------
......
......@@ -91,7 +91,7 @@ bool cmCTestBuildCommand::InitialPass(
m_CTest->SetCTestConfiguration("BuildDirectory", build_dir);
}
cmCTestGenericHandler* handler = m_CTest->GetHandler("build");
cmCTestGenericHandler* handler = m_CTest->GetInitializedHandler("build");
if ( !handler )
{
this->SetError("internal CTest error. Cannot instantiate build handler");
......
......@@ -189,6 +189,7 @@ cmCTestBuildHandler::cmCTestBuildHandler()
//----------------------------------------------------------------------
void cmCTestBuildHandler::Initialize()
{
this->Superclass::Initialize();
m_StartBuild = "";
m_EndBuild = "";
m_CustomErrorMatches.clear();
......@@ -282,9 +283,9 @@ int cmCTestBuildHandler::ProcessHandler()
// Create a last build log
cmGeneratedFileStream ofs;
double elapsed_time_start = cmSystemTools::GetTime();
if ( !m_CTest->OpenOutputFile("Temporary", "LastBuild.log", ofs) )
if ( !this->StartLogFile("Build", ofs) )
{
cmCTestLog(m_CTest, ERROR_MESSAGE, "Cannot create LastBuild.log file" << std::endl);
cmCTestLog(m_CTest, ERROR_MESSAGE, "Cannot create build log file" << std::endl);
}
// Create lists of regular expression strings for errors, error exceptions,
......@@ -414,7 +415,7 @@ int cmCTestBuildHandler::ProcessHandler()
// Generate XML output
cmGeneratedFileStream xofs;
if( !m_CTest->OpenOutputFile(m_CTest->GetCurrentTag(), "Build.xml", xofs, true) )
if( !this->StartResultingXML("Build", xofs))
{
cmCTestLog(m_CTest, ERROR_MESSAGE, "Cannot create build XML file" << std::endl);
return -1;
......
......@@ -132,7 +132,7 @@ bool cmCTestConfigureCommand::InitialPass(
}
}
cmCTestGenericHandler* handler = m_CTest->GetHandler("configure");
cmCTestGenericHandler* handler = m_CTest->GetInitializedHandler("configure");
if ( !handler )
{
this->SetError("internal CTest error. Cannot instantiate configure handler");
......
......@@ -31,6 +31,7 @@ cmCTestConfigureHandler::cmCTestConfigureHandler()
//----------------------------------------------------------------------
void cmCTestConfigureHandler::Initialize()
{
this->Superclass::Initialize();
}
//----------------------------------------------------------------------
......@@ -61,7 +62,7 @@ int cmCTestConfigureHandler::ProcessHandler()
if ( !m_CTest->GetShowOnly() )
{
cmGeneratedFileStream os;
if ( !m_CTest->OpenOutputFile(m_CTest->GetCurrentTag(), "Configure.xml", os, true) )
if ( !this->StartResultingXML("Configure", os) )
{
cmCTestLog(m_CTest, ERROR_MESSAGE, "Cannot open configure file" << std::endl);
return 1;
......@@ -69,7 +70,7 @@ int cmCTestConfigureHandler::ProcessHandler()
std::string start_time = m_CTest->CurrentTime();
cmGeneratedFileStream ofs;
m_CTest->OpenOutputFile("Temporary", "LastConfigure.log", ofs);
this->StartLogFile("Configure", ofs);
cmCTestLog(m_CTest, HANDLER_VERBOSE_OUTPUT, "Configure with command: " << cCommand.c_str() << std::endl);
res = m_CTest->RunMakeCommand(cCommand.c_str(), &output,
&retVal, buildDirectory.c_str(),
......
......@@ -74,7 +74,7 @@ bool cmCTestCoverageCommand::InitialPass(
m_CTest->SetCTestConfigurationFromCMakeVariable(m_Makefile,
"CoverageCommand", "CTEST_COVERAGE_COMMAND");
cmCTestGenericHandler* handler = m_CTest->GetHandler("coverage");
cmCTestGenericHandler* handler = m_CTest->GetInitializedHandler("coverage");
if ( !handler )
{
this->SetError("internal CTest error. Cannot instantiate test handler");
......
......@@ -39,16 +39,16 @@ cmCTestCoverageHandler::cmCTestCoverageHandler()
//----------------------------------------------------------------------
void cmCTestCoverageHandler::Initialize()
{
this->Superclass::Initialize();
}
//----------------------------------------------------------------------
bool cmCTestCoverageHandler::StartLogFile(cmGeneratedFileStream& covLogFile, int logFileCount)
bool cmCTestCoverageHandler::StartCoverageLogFile(cmGeneratedFileStream& covLogFile, int logFileCount)
{
char covLogFilename[1024];
sprintf(covLogFilename, "CoverageLog-%d.xml", logFileCount);
sprintf(covLogFilename, "CoverageLog-%d", logFileCount);
cmCTestLog(m_CTest, HANDLER_VERBOSE_OUTPUT, "Open file: " << covLogFilename << std::endl);
if (!m_CTest->OpenOutputFile(m_CTest->GetCurrentTag(),
covLogFilename, covLogFile, true))
if (!this->StartResultingXML(covLogFilename, covLogFile) )
{
cmCTestLog(m_CTest, ERROR_MESSAGE, "Cannot open log file: " << covLogFilename << std::endl);
return false;
......@@ -61,7 +61,7 @@ bool cmCTestCoverageHandler::StartLogFile(cmGeneratedFileStream& covLogFile, int
}
//----------------------------------------------------------------------
void cmCTestCoverageHandler::EndLogFile(cmGeneratedFileStream& ostr, int logFileCount)
void cmCTestCoverageHandler::EndCoverageLogFile(cmGeneratedFileStream& ostr, int logFileCount)
{
std::string local_end_time = m_CTest->CurrentTime();
ostr << "\t<EndDateTime>" << local_end_time << "</EndDateTime>" << std::endl
......@@ -161,7 +161,7 @@ int cmCTestCoverageHandler::ProcessHandler()
cmGeneratedFileStream ofs;
double elapsed_time_start = cmSystemTools::GetTime();
if ( !m_CTest->OpenOutputFile("Temporary", "LastCoverage.log", ofs) )
if ( !this->StartLogFile("Coverage", ofs) )
{
cmCTestLog(m_CTest, ERROR_MESSAGE, "Cannot create LastCoverage.log file" << std::endl);
}
......@@ -333,10 +333,9 @@ int cmCTestCoverageHandler::ProcessHandler()
cmGeneratedFileStream covSumFile;
cmGeneratedFileStream covLogFile;
if (!m_CTest->OpenOutputFile(m_CTest->GetCurrentTag(),
"Coverage.xml", covSumFile, true))
if (!this->StartResultingXML("Coverage", covSumFile))
{
cmCTestLog(m_CTest, ERROR_MESSAGE, "Cannot open coverage summary file: Coverage.xml" << std::endl);
cmCTestLog(m_CTest, ERROR_MESSAGE, "Cannot open coverage summary file." << std::endl);
return -1;
}
......@@ -347,7 +346,7 @@ int cmCTestCoverageHandler::ProcessHandler()
covSumFile << "<Coverage>" << std::endl
<< "\t<StartDateTime>" << coverage_start_time << "</StartDateTime>" << std::endl;
int logFileCount = 0;
if ( !this->StartLogFile(covLogFile, logFileCount) )
if ( !this->StartCoverageLogFile(covLogFile, logFileCount) )
{
return -1;
}
......@@ -364,9 +363,9 @@ int cmCTestCoverageHandler::ProcessHandler()
if ( cnt == 100 )
{
cnt = 0;
this->EndLogFile(covLogFile, logFileCount);
this->EndCoverageLogFile(covLogFile, logFileCount);
logFileCount ++;
if ( !this->StartLogFile(covLogFile, logFileCount) )
if ( !this->StartCoverageLogFile(covLogFile, logFileCount) )
{
return -1;
}
......@@ -468,7 +467,7 @@ int cmCTestCoverageHandler::ProcessHandler()
<< "\t</File>" << std::endl;
cnt ++;
}
this->EndLogFile(covLogFile, logFileCount);
this->EndCoverageLogFile(covLogFile, logFileCount);
int total_lines = total_tested + total_untested;
float percent_coverage = 100 * SAFEDIV(static_cast<float>(total_tested),
......
......@@ -45,8 +45,8 @@ public:
private:
bool ShouldIDoCoverage(const char* file, const char* srcDir,
const char* binDir);
bool StartLogFile(cmGeneratedFileStream& ostr, int logFileCount);
void EndLogFile(cmGeneratedFileStream& ostr, int logFileCount);
bool StartCoverageLogFile(cmGeneratedFileStream& ostr, int logFileCount);
void EndCoverageLogFile(cmGeneratedFileStream& ostr, int logFileCount);
struct cmCTestCoverage
{
......
......@@ -17,11 +17,14 @@
#include "cmCTestGenericHandler.h"
#include "cmCTest.h"
//----------------------------------------------------------------------
cmCTestGenericHandler::cmCTestGenericHandler()
{
m_HandlerVerbose = false;
m_CTest = 0;
m_SubmitIndex = 0;
}
//----------------------------------------------------------------------
......@@ -50,6 +53,12 @@ void cmCTestGenericHandler::SetOption(const char* op, const char* value)
m_Options[op] = value;
}
//----------------------------------------------------------------------
void cmCTestGenericHandler::Initialize()
{
m_Options.clear();
}
//----------------------------------------------------------------------
const char* cmCTestGenericHandler::GetOption(const char* op)
{
......@@ -62,3 +71,51 @@ const char* cmCTestGenericHandler::GetOption(const char* op)
return remit->second.c_str();
}
//----------------------------------------------------------------------
bool cmCTestGenericHandler::StartResultingXML(const char* name, cmGeneratedFileStream& xofs)
{
if ( !name )
{
cmCTestLog(m_CTest, ERROR_MESSAGE, "Cannot create resulting XML file without providing the name" << std::endl;);
return false;
}
cmOStringStream ostr;
ostr << name;
if ( m_SubmitIndex > 0 )
{
ostr << "_" << m_SubmitIndex;
}
ostr << ".xml";
if( !m_CTest->OpenOutputFile(m_CTest->GetCurrentTag(), ostr.str().c_str(), xofs, true) )
{
cmCTestLog(m_CTest, ERROR_MESSAGE, "Cannot create resulting XML file: " << ostr.str().c_str() << std::endl);
return false;
}
m_CTest->AddSubmitFile(ostr.str().c_str());
return true;
}
//----------------------------------------------------------------------
bool cmCTestGenericHandler::StartLogFile(const char* name, cmGeneratedFileStream& xofs)
{
if ( !name )
{
cmCTestLog(m_CTest, ERROR_MESSAGE, "Cannot create log file without providing the name" << std::endl;);
return false;
}
cmOStringStream ostr;
ostr << "Last" << name;
if ( m_SubmitIndex > 0 )
{
ostr << "_" << m_SubmitIndex;
}
ostr << "_" << m_CTest->GetCurrentTag();
ostr << ".log";
if( !m_CTest->OpenOutputFile("Temporary", ostr.str().c_str(), xofs) )
{
cmCTestLog(m_CTest, ERROR_MESSAGE, "Cannot create log file: " << ostr.str().c_str() << std::endl);
return false;
}
return true;
}
......@@ -24,6 +24,7 @@
class cmCTest;
class cmMakefile;
class cmCTestCommand;
class cmGeneratedFileStream;
/** \class cmCTestGenericHandler
* \brief A superclass of all CTest Handlers
......@@ -58,7 +59,7 @@ public:
/**
* Initialize handler
*/
virtual void Initialize() = 0;
virtual void Initialize();
/**
* Set the CTest instance
......@@ -82,12 +83,19 @@ public:
m_Command = command;
}
void SetSubmitIndex(int idx) { m_SubmitIndex = idx; }
int GetSubmitIndex() { return m_SubmitIndex; }
protected:
bool StartResultingXML(const char* name, cmGeneratedFileStream& xofs);
bool StartLogFile(const char* name, cmGeneratedFileStream& xofs);
bool m_HandlerVerbose;
cmCTest *m_CTest;
t_StringToString m_Options;
cmCTestCommand* m_Command;
int m_SubmitIndex;
};
#endif
......
/*=========================================================================
Program: CMake - Cross-Platform Makefile Generator
Module: $RCSfile$
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
#include "cmCTestHandlerCommand.h"
#include "cmCTest.h"
#include "cmCTestGenericHandler.h"
cmCTestHandlerCommand::cmCTestHandlerCommand()
{
const size_t INIT_SIZE = 100;
size_t cc;
m_Arguments.reserve(INIT_SIZE);
for ( cc = 0; cc < INIT_SIZE; ++ cc )
{
m_Arguments[cc] = 0;
}
m_Arguments[ct_RETURN_VALUE] = "RETURN_VALUE";
m_Arguments[ct_SOURCE] = "SOURCE";
m_Arguments[ct_BUILD] = "BUILD";
m_Arguments[ct_SUBMIT_INDEX] = "SUBMIT_INDEX";
m_Last = ct_LAST;
}
bool cmCTestHandlerCommand::InitialPass(
std::vector<std::string> const& args)
{
if ( !this->ProcessArguments(args, m_Last, &*m_Arguments.begin(), m_Values) )
{
return false;
}
cmCTestGenericHandler* handler = this->InitializeHandler();
if ( !handler )
{
this->SetError("internal CTest error. Cannot instantiate test handler");
return false;
}
if ( m_Values[ct_BUILD] )
{
m_CTest->SetCTestConfiguration("BuildDirectory", m_Values[ct_BUILD]);
}
if ( m_Values[ct_SUBMIT_INDEX] )
{
if ( m_CTest->GetDartVersion() <= 1 )
{
cmCTestLog(m_CTest, ERROR_MESSAGE, "Dart before version 2.0 does not support collecting submissions." << std::endl
<< "Please upgrade the server to Dart 2 or higher, or do not use SUBMIT_INDEX." << std::endl);
}
else
{
handler->SetSubmitIndex(atoi(m_Values[ct_SUBMIT_INDEX]));
}
}
std::string current_dir = cmSystemTools::GetCurrentWorkingDirectory();
cmSystemTools::ChangeDirectory(m_CTest->GetCTestConfiguration("BuildDirectory").c_str());
int res = handler->ProcessHandler();
if ( m_Values[ct_RETURN_VALUE] && *m_Values[ct_RETURN_VALUE])
{
cmOStringStream str;
str << res;
m_Makefile->AddDefinition(m_Values[ct_RETURN_VALUE], str.str().c_str());
}
cmSystemTools::ChangeDirectory(current_dir.c_str());
return true;
}
bool cmCTestHandlerCommand::ProcessArguments(std::vector<std::string> const& args,
int last, const char** strings, std::vector<const char*>& values)
{
int state = 0;
int cc;
values.resize(last);
for ( cc = 0; cc < last; ++ cc )
{
values[cc] = 0;
}
for(size_t i=0; i < args.size(); ++i)
{
if ( state > 0 && state < last )
{
values[state] = args[i].c_str();
#undef cerr
cmCTestLog(m_CTest, DEBUG, "Set " << strings[state] << " to " << args[i].c_str() << std::endl);
state = 0;
}
else
{
bool found = false;
for ( cc = 0; cc < last; ++ cc )
{
if ( strings[cc] && args[i] == strings[cc] )
{
state = cc;
if ( values[state] )
{
cmOStringStream ostr;
ostr << "called with incorrect number of arguments. " << strings[state] << " specified twice.";
this->SetError(ostr.str().c_str());
return false;
}
found = true;
break;
}
}
if ( !found )
{
cmOStringStream str;
str << "called with incorrect number of arguments. Extra argument is: " << args[i].c_str() << ".";
this->SetError(str.str().c_str());
return false;
}
}
}
return true;
}
/*=========================================================================
Program: CMake - Cross-Platform Makefile Generator
Module: $RCSfile$
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
#ifndef cmCTestHandlerCommand_h
#define cmCTestHandlerCommand_h
#include "cmCTestCommand.h"
class cmCTestGenericHandler;
/** \class cmCTestHandler
* \brief Run a ctest script
*
* cmCTestHandlerCommand defineds the command to test the project.
*/
class cmCTestHandlerCommand : public cmCTestCommand
{
public:
cmCTestHandlerCommand();
/**
* This is called when the command is first encountered in
* the CMakeLists.txt file.
*/
virtual bool InitialPass(std::vector<std::string> const& args);
cmTypeMacro(cmCTestHandlerCommand, cmCTestCommand);
enum
{
ct_NONE,
ct_RETURN_VALUE,
ct_BUILD,
ct_SOURCE,
ct_SUBMIT_INDEX,
ct_LAST
};
protected:
virtual cmCTestGenericHandler* InitializeHandler() = 0;
bool ProcessArguments(std::vector<std::string> const& args,
int last, const char** strings, std::vector<const char*>& values);
std::string m_ReturnVariable;
std::vector<const char*> m_Arguments;
std::vector<const char*> m_Values;
size_t m_Last;
};
#endif
......@@ -19,57 +19,10 @@
#include "cmCTest.h"
#include "cmCTestGenericHandler.h"
bool cmCTestMemCheckCommand::InitialPass(
std::vector<std::string> const& args)
{
const char* build_dir = 0;
const char* res_var = 0;
bool havereturn_variable = false;
bool havesource = false;
for(size_t i=0; i < args.size(); ++i)
{
if ( havereturn_variable )
{
res_var = args[i].c_str();
havereturn_variable = false;
}
else if ( havesource )
{
build_dir = args[i].c_str();
havesource = false;
}
else if(args[i] == "RETURN_VALUE")
{
if ( res_var )
{
this->SetError("called with incorrect number of arguments. RETURN_VALUE specified twice.");
return false;
}
havereturn_variable = true;
}
else if(args[i] == "BUILD")
{
if ( build_dir )
{
this->SetError("called with incorrect number of arguments. BUILD specified twice.");
return false;
}
havesource = true;
}
else
{
cmOStringStream str;
str << "called with incorrect number of arguments. Extra argument is: " << args[i].c_str() << ".";
this->SetError(str.str().c_str());
return false;
}
}
if ( build_dir )
{
m_CTest->SetCTestConfiguration("BuildDirectory", build_dir);
}
cmCTestGenericHandler* cmCTestMemCheckCommand::InitializeActualHandler()
{
cmCTestGenericHandler* handler = m_CTest->GetInitializedHandler("memcheck");
m_CTest->SetCTestConfigurationFromCMakeVariable(m_Makefile,
"MemoryCheckCommand", "CTEST_MEMORYCHECK_COMMAND");
......@@ -78,24 +31,6 @@ bool cmCTestMemCheckCommand::InitialPass(
m_CTest->SetCTestConfigurationFromCMakeVariable(m_Makefile,
"MemoryCheckSuppressionFile", "CTEST_MEMORYCHECK_SUPPRESSIONS_FILE");
cmCTestGenericHandler* handler = m_CTest->GetHandler("memcheck");
if ( !handler )
{
this->SetError("internal CTest error. Cannot instantiate test handler");
return false;
}
std::string current_dir = cmSystemTools::GetCurrentWorkingDirectory();
cmSystemTools::ChangeDirectory(m_CTest->GetCTestConfiguration("BuildDirectory").c_str());
int res = handler->ProcessHandler();
if ( res_var )
{
cmOStringStream str;
str << res;
m_Makefile->AddDefinition(res_var, str.str().c_str());
}
cmSystemTools::ChangeDirectory(current_dir.c_str());
return true;
return handler;
}
......@@ -17,14 +17,16 @@
#ifndef cmCTestMemCheckCommand_h
#define cmCTestMemCheckCommand_h
#include "cmCTestCommand.h"
#include "cmCTestTestCommand.h"
class cmCTestGenericHandler;
/** \class cmCTestMemCheck