Commit c7feef30 authored by Andy Cedilnik's avatar Andy Cedilnik

ENH: Promote submit into a full handler, add test and submit command and do some cleanups

parent 4675aed7
SET (CTEST_PROJECT_NAME "CMake")
SET (CTEST_NIGHTLY_START_TIME "21:00:00 EDT")
SET (CTEST_DROP_METHOD "http")
SET (CTEST_DROP_SITE "public.kitware.com")
SET (CTEST_DROP_LOCATION "/cgi-bin/HTTPUploadDartFile.cgi")
SET (CTEST_TRIGGER_SITE
"http://${DROP_SITE}/cgi-bin/Submit-CMake-TestingResults.cgi")
SET (CTEST_TRIGGER_SITE "http://${CTEST_DROP_SITE}/cgi-bin/Submit-CMake-TestingResults.cgi")
......@@ -163,7 +163,9 @@ SET(CMTEST_SRCS cmCTest.cxx
CTest/cmCTestScriptHandler.cxx
CTest/cmCTestSleepCommand.cxx
CTest/cmCTestStartCommand.cxx
CTest/cmCTestSubmit.cxx
CTest/cmCTestSubmitCommand.cxx
CTest/cmCTestSubmitHandler.cxx
CTest/cmCTestTestCommand.cxx
CTest/cmCTestTestHandler.cxx
CTest/cmCTestUpdateCommand.cxx
CTest/cmCTestUpdateHandler.cxx
......
......@@ -197,13 +197,13 @@ void cmCTestBuildHandler::PopulateCustomVectors(cmMakefile *mf)
int cmCTestBuildHandler::ProcessHandler()
{
std::cout << "Build project" << std::endl;
std::string makeCommand = m_CTest->GetDartConfiguration("MakeCommand");
const std::string &makeCommand = m_CTest->GetDartConfiguration("MakeCommand");
if ( makeCommand.size() == 0 )
{
std::cerr << "Cannot find MakeCommand key in the DartConfiguration.tcl" << std::endl;
return -1;
}
std::string buildDirectory = m_CTest->GetDartConfiguration("BuildDirectory");
const std::string &buildDirectory = m_CTest->GetDartConfiguration("BuildDirectory");
if ( buildDirectory.size() == 0 )
{
std::cerr << "Cannot find BuildDirectory key in the DartConfiguration.tcl" << std::endl;
......
......@@ -49,6 +49,8 @@
#include "cmCTestSleepCommand.h"
#include "cmCTestStartCommand.h"
#include "cmCTestUpdateCommand.h"
#include "cmCTestTestCommand.h"
#include "cmCTestSubmitCommand.h"
#define CTEST_INITIAL_CMAKE_OUTPUT_FILE_NAME "CTestInitialCMakeOutput.log"
......@@ -229,6 +231,8 @@ int cmCTestScriptHandler::ReadInScript(const std::string& total_script_arg)
this->AddCTestCommand(new cmCTestRunScriptCommand);
this->AddCTestCommand(new cmCTestSleepCommand);
this->AddCTestCommand(new cmCTestStartCommand);
this->AddCTestCommand(new cmCTestSubmitCommand);
this->AddCTestCommand(new cmCTestTestCommand);
this->AddCTestCommand(new cmCTestUpdateCommand);
// add the script arg if defined
......
/*=========================================================================
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 "cmCTestSubmitCommand.h"
#include "cmCTest.h"
#include "cmCTestGenericHandler.h"
bool cmCTestSubmitCommand::InitialPass(
std::vector<std::string> const& args)
{
if (args.size() != 1)
{
this->SetError("called with incorrect number of arguments");
return false;
}
const char* res_var = args[0].c_str();
m_CTest->SetDartConfigurationFromCMakeVariable(m_Makefile, "DropMethod", "CTEST_DROP_METHOD");
m_CTest->SetDartConfigurationFromCMakeVariable(m_Makefile, "DropSite", "CTEST_DROP_SITE");
m_CTest->SetDartConfigurationFromCMakeVariable(m_Makefile, "DropLocation", "CTEST_DROP_LOCATION");
m_CTest->SetDartConfigurationFromCMakeVariable(m_Makefile, "DropSiteUser", "CTEST_DROP_SITE_USER");
m_CTest->SetDartConfigurationFromCMakeVariable(m_Makefile, "DropSitePassword", "CTEST_DROP_SITE_PASSWORD");
m_CTest->SetDartConfigurationFromCMakeVariable(m_Makefile, "TriggerSite", "CTEST_TRIGGER_SITE");
m_CTest->SetDartConfigurationFromCMakeVariable(m_Makefile, "ScpCommand", "CTEST_SCP_COMMAND");
cmCTestGenericHandler* handler = m_CTest->GetHandler("submit");
if ( !handler )
{
this->SetError("internal CTest error. Cannot instantiate submit handler");
return false;
}
int res = handler->ProcessHandler();
cmOStringStream str;
str << res;
m_Makefile->AddDefinition(res_var, str.str().c_str());
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 cmCTestSubmitCommand_h
#define cmCTestSubmitCommand_h
#include "cmCTestCommand.h"
/** \class cmCTestSubmit
* \brief Run a ctest script
*
* cmCTestSubmitCommand defineds the command to submit the test results for the project.
*/
class cmCTestSubmitCommand : public cmCTestCommand
{
public:
cmCTestSubmitCommand() {}
/**
* This is a virtual constructor for the command.
*/
virtual cmCommand* Clone()
{
cmCTestSubmitCommand* ni = new cmCTestSubmitCommand;
ni->m_CTest = this->m_CTest;
ni->m_CTestScriptHandler = this->m_CTestScriptHandler;
return ni;
}
/**
* This is called when the command is first encountered in
* the CMakeLists.txt file.
*/
virtual bool InitialPass(std::vector<std::string> const& args);
/**
* The name of the command as specified in CMakeList.txt.
*/
virtual const char* GetName() { return "CTEST_SUBMIT";}
/**
* Succinct documentation.
*/
virtual const char* GetTerseDocumentation()
{
return "Submits the repository.";
}
/**
* More documentation.
*/
virtual const char* GetFullDocumentation()
{
return
" CTEST_SUBMIT(res)\n"
"Submits the test results for the project.";
}
cmTypeMacro(cmCTestSubmitCommand, cmCTestCommand);
};
#endif
......@@ -14,22 +14,27 @@ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
#include "cmCTestSubmitHandler.h"
#include "cmCTestSubmit.h"
#include "cmSystemTools.h"
#include "cmVersion.h"
#include "cmGeneratedFileStream.h"
#include "cmCTest.h"
#include <cmsys/Process.h>
#include <cmsys/Base64.h>
// For XML-RPC submission
#include "xmlrpc.h"
#include "xmlrpc_client.h"
// For curl submission
#include "CTest/Curl/curl/curl.h"
#include <sys/stat.h>
//----------------------------------------------------------------------------
cmCTestSubmit::cmCTestSubmit() : m_HTTPProxy(), m_FTPProxy()
cmCTestSubmitHandler::cmCTestSubmitHandler() : m_HTTPProxy(), m_FTPProxy()
{
m_Verbose = false;
m_HTTPProxy = "";
......@@ -111,7 +116,7 @@ cmCTestSubmit::cmCTestSubmit() : m_HTTPProxy(), m_FTPProxy()
}
//----------------------------------------------------------------------------
bool cmCTestSubmit::SubmitUsingFTP(const cmStdString& localprefix,
bool cmCTestSubmitHandler::SubmitUsingFTP(const cmStdString& localprefix,
const std::vector<cmStdString>& files,
const cmStdString& remoteprefix,
const cmStdString& url)
......@@ -208,7 +213,7 @@ bool cmCTestSubmit::SubmitUsingFTP(const cmStdString& localprefix,
//----------------------------------------------------------------------------
// Uploading files is simpler
bool cmCTestSubmit::SubmitUsingHTTP(const cmStdString& localprefix,
bool cmCTestSubmitHandler::SubmitUsingHTTP(const cmStdString& localprefix,
const std::vector<cmStdString>& files,
const cmStdString& remoteprefix,
const cmStdString& url)
......@@ -343,7 +348,7 @@ bool cmCTestSubmit::SubmitUsingHTTP(const cmStdString& localprefix,
}
//----------------------------------------------------------------------------
bool cmCTestSubmit::TriggerUsingHTTP(const std::vector<cmStdString>& files,
bool cmCTestSubmitHandler::TriggerUsingHTTP(const std::vector<cmStdString>& files,
const cmStdString& remoteprefix,
const cmStdString& url)
{
......@@ -443,7 +448,7 @@ bool cmCTestSubmit::TriggerUsingHTTP(const std::vector<cmStdString>& files,
}
//----------------------------------------------------------------------------
bool cmCTestSubmit::SubmitUsingSCP(
bool cmCTestSubmitHandler::SubmitUsingSCP(
const cmStdString& scp_command,
const cmStdString& localprefix,
const std::vector<cmStdString>& files,
......@@ -552,7 +557,7 @@ bool cmCTestSubmit::SubmitUsingSCP(
}
//----------------------------------------------------------------------------
bool cmCTestSubmit::SubmitUsingXMLRPC(const cmStdString& localprefix,
bool cmCTestSubmitHandler::SubmitUsingXMLRPC(const cmStdString& localprefix,
const std::vector<cmStdString>& files,
const cmStdString& remoteprefix,
const cmStdString& url)
......@@ -610,7 +615,7 @@ bool cmCTestSubmit::SubmitUsingXMLRPC(const cmStdString& localprefix,
std::cerr << " Submission problem: " << env.fault_string << " (" << env.fault_code << ")" << std::endl;
xmlrpc_env_clean(&env);
xmlrpc_client_cleanup();
return 0;
return false;
}
......@@ -622,7 +627,7 @@ bool cmCTestSubmit::SubmitUsingXMLRPC(const cmStdString& localprefix,
xmlrpc_DECREF(result);
xmlrpc_env_clean(&env);
xmlrpc_client_cleanup();
return 0;
return false;
}
/* Dispose of our result value. */
......@@ -634,5 +639,175 @@ bool cmCTestSubmit::SubmitUsingXMLRPC(const cmStdString& localprefix,
/* Shutdown our XML-RPC client library. */
xmlrpc_client_cleanup();
return 1;
return true;
}
//----------------------------------------------------------------------------
int cmCTestSubmitHandler::ProcessHandler()
{
const std::string &buildDirectory = m_CTest->GetDartConfiguration("BuildDirectory");
if ( buildDirectory.size() == 0 )
{
std::cerr << "Cannot find BuildDirectory key in the DartConfiguration.tcl" << std::endl;
return -1;
}
cmGeneratedFileStream ofs;
m_CTest->OpenOutputFile("Temporary", "LastSubmit.log", ofs);
cmCTest::tm_VectorOfStrings files;
std::string prefix = this->GetSubmitResultsPrefix();
// TODO:
// Check if test is enabled
m_CTest->AddIfExists(files, "Update.xml");
m_CTest->AddIfExists(files, "Configure.xml");
m_CTest->AddIfExists(files, "Build.xml");
m_CTest->AddIfExists(files, "Test.xml");
if ( m_CTest->AddIfExists(files, "Coverage.xml") )
{
cmCTest::tm_VectorOfStrings gfiles;
std::string gpath = buildDirectory + "/Testing/" + m_CTest->GetCurrentTag();
std::string::size_type glen = gpath.size() + 1;
gpath = gpath + "/CoverageLog*";
//std::cout << "Globbing for: " << gpath.c_str() << std::endl;
if ( cmSystemTools::SimpleGlob(gpath, gfiles, 1) )
{
size_t cc;
for ( cc = 0; cc < gfiles.size(); cc ++ )
{
gfiles[cc] = gfiles[cc].substr(glen);
//std::cout << "Glob file: " << gfiles[cc].c_str() << std::endl;
files.push_back(gfiles[cc]);
}
}
else
{
std::cerr << "Problem globbing" << std::endl;
}
}
m_CTest->AddIfExists(files, "DynamicAnalysis.xml");
m_CTest->AddIfExists(files, "Purify.xml");
m_CTest->AddIfExists(files, "Notes.xml");
if ( ofs )
{
ofs << "Upload files:" << std::endl;
int cnt = 0;
cmCTest::tm_VectorOfStrings::iterator it;
for ( it = files.begin(); it != files.end(); ++ it )
{
ofs << cnt << "\t" << it->c_str() << std::endl;
cnt ++;
}
}
std::cout << "Submit files (using " << m_CTest->GetDartConfiguration("DropMethod") << ")"
<< std::endl;
this->SetLogFile(&ofs);
if ( m_CTest->GetDartConfiguration("DropMethod") == "" ||
m_CTest->GetDartConfiguration("DropMethod") == "ftp" )
{
ofs << "Using drop method: FTP" << std::endl;
std::cout << " Using FTP submit method" << std::endl;
std::string url = "ftp://";
url += cmCTest::MakeURLSafe(m_CTest->GetDartConfiguration("DropSiteUser")) + ":" +
cmCTest::MakeURLSafe(m_CTest->GetDartConfiguration("DropSitePassword")) + "@" +
m_CTest->GetDartConfiguration("DropSite") +
cmCTest::MakeURLSafe(m_CTest->GetDartConfiguration("DropLocation"));
if ( !this->SubmitUsingFTP(buildDirectory+"/Testing/"+m_CTest->GetCurrentTag(),
files, prefix, url) )
{
std::cerr << " Problems when submitting via FTP" << std::endl;
ofs << " Problems when submitting via FTP" << std::endl;
return -1;
}
if ( !this->TriggerUsingHTTP(files, prefix, m_CTest->GetDartConfiguration("TriggerSite")) )
{
std::cerr << " Problems when triggering via HTTP" << std::endl;
ofs << " Problems when triggering via HTTP" << std::endl;
return -1;
}
std::cout << " Submission successful" << std::endl;
ofs << " Submission successful" << std::endl;
return 0;
}
else if ( m_CTest->GetDartConfiguration("DropMethod") == "http" )
{
ofs << "Using drop method: HTTP" << std::endl;
std::cout << " Using HTTP submit method" << std::endl;
std::string url = "http://";
if ( m_CTest->GetDartConfiguration("DropSiteUser").size() > 0 )
{
url += m_CTest->GetDartConfiguration("DropSiteUser");
if ( m_CTest->GetDartConfiguration("DropSitePassword").size() > 0 )
{
url += ":" + m_CTest->GetDartConfiguration("DropSitePassword");
}
url += "@";
}
url += m_CTest->GetDartConfiguration("DropSite") + m_CTest->GetDartConfiguration("DropLocation");
if ( !this->SubmitUsingHTTP(buildDirectory +"/Testing/"+m_CTest->GetCurrentTag(), files, prefix, url) )
{
std::cerr << " Problems when submitting via HTTP" << std::endl;
ofs << " Problems when submitting via HTTP" << std::endl;
return -1;
}
if ( !this->TriggerUsingHTTP(files, prefix, m_CTest->GetDartConfiguration("TriggerSite")) )
{
std::cerr << " Problems when triggering via HTTP" << std::endl;
ofs << " Problems when triggering via HTTP" << std::endl;
return -1;
}
std::cout << " Submission successful" << std::endl;
ofs << " Submission successful" << std::endl;
return 0;
}
else if ( m_CTest->GetDartConfiguration("DropMethod") == "xmlrpc" )
{
ofs << "Using drop method: XML-RPC" << std::endl;
std::cout << " Using XML-RPC submit method" << std::endl;
std::string url = m_CTest->GetDartConfiguration("DropSite");
prefix = m_CTest->GetDartConfiguration("DropLocation");
if ( !this->SubmitUsingXMLRPC(buildDirectory+"/Testing/"+m_CTest->GetCurrentTag(), files, prefix, url) )
{
std::cerr << " Problems when submitting via XML-RPC" << std::endl;
ofs << " Problems when submitting via XML-RPC" << std::endl;
return -1;
}
std::cout << " Submission successful" << std::endl;
ofs << " Submission successful" << std::endl;
return 0;
}
else if ( m_CTest->GetDartConfiguration("DropMethod") == "scp" )
{
std::string url;
if ( m_CTest->GetDartConfiguration("DropSiteUser").size() > 0 )
{
url += m_CTest->GetDartConfiguration("DropSiteUser") + "@";
}
url += m_CTest->GetDartConfiguration("DropSite") + ":" + m_CTest->GetDartConfiguration("DropLocation");
if ( !this->SubmitUsingSCP(m_CTest->GetDartConfiguration("ScpCommand"),
buildDirectory+"/Testing/"+m_CTest->GetCurrentTag(), files, prefix, url) )
{
std::cerr << " Problems when submitting via SCP" << std::endl;
ofs << " Problems when submitting via SCP" << std::endl;
return -1;
}
std::cout << " Submission successful" << std::endl;
ofs << " Submission successful" << std::endl;
}
std::cout << " Unknown submission method: \"" << m_CTest->GetDartConfiguration("DropMethod") << "\"" << std::endl;
return -1;
}
//----------------------------------------------------------------------------
std::string cmCTestSubmitHandler::GetSubmitResultsPrefix()
{
std::string name = m_CTest->GetDartConfiguration("Site") +
"___" + m_CTest->GetDartConfiguration("BuildName") +
"___" + m_CTest->GetCurrentTag() + "-" +
m_CTest->GetTestModelString() + "___XML___";
return name;
}
......@@ -14,32 +14,32 @@
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
#ifndef cmCTestSubmit_h
#define cmCTestSubmit_h
#ifndef cmCTestSubmitHandler_h
#define cmCTestSubmitHandler_h
#include "cmStandardIncludes.h"
#include "cmCTestGenericHandler.h"
/** \class cmCTestSubmit
/** \class cmCTestSubmitHandler
* \brief Helper class for CTest
*
* Submit testing results
*
*/
class cmCTestSubmit
class cmCTestSubmitHandler : public cmCTestGenericHandler
{
public:
cmCTestSubmit();
~cmCTestSubmit() { m_LogFile = 0; }
cmCTestSubmitHandler();
~cmCTestSubmitHandler() { m_LogFile = 0; }
/**
* Set verbosity of send
/*
* The main entry point for this class
*/
void SetVerbose(bool i) { m_Verbose = i; }
void VerboseOn() { this->SetVerbose(1); }
void VerboseOff() { this->SetVerbose(0); }
int ProcessHandler();
void SetLogFile(std::ostream* ost) { m_LogFile = ost; }
private:
void SetLogFile(std::ostream* ost) { m_LogFile = ost; }
/**
* Submit file using various ways
*/
......@@ -66,13 +66,13 @@ public:
const cmStdString& remoteprefix,
const cmStdString& url);
private:
std::string GetSubmitResultsPrefix();
cmStdString m_HTTPProxy;
int m_HTTPProxyType;
cmStdString m_HTTPProxyAuth;
cmStdString m_FTPProxy;
int m_FTPProxyType;
bool m_Verbose;
std::ostream* m_LogFile;
};
......
/*=========================================================================
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 "cmCTestTestCommand.h"
#include "cmCTest.h"
#include "cmCTestGenericHandler.h"
bool cmCTestTestCommand::InitialPass(
std::vector<std::string> const& args)
{
if (args.size() != 2)
{
this->SetError("called with incorrect number of arguments");
return false;
}
const char* build_dir = args[0].c_str();
const char* res_var = args[1].c_str();
m_CTest->SetDartConfiguration("BuildDirectory", build_dir);
cmCTestGenericHandler* handler = m_CTest->GetHandler("test");
if ( !handler )
{
this->SetError("internal CTest error. Cannot instantiate test handler");
return false;
}
std::string current_dir = cmSystemTools::GetCurrentWorkingDirectory();
cmSystemTools::ChangeDirectory(build_dir);
int res = handler->ProcessHandler();
cmSystemTools::ChangeDirectory(current_dir.c_str());
cmOStringStream str;
str << res;
m_Makefile->AddDefinition(res_var, str.str().c_str());
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 cmCTestTestCommand_h
#define cmCTestTestCommand_h
#include "cmCTestCommand.h"
/** \class cmCTestTest
* \brief Run a ctest script
*
* cmCTestTestCommand defineds the command to test the project.
*/
class cmCTestTestCommand : public cmCTestCommand
{
public:
cmCTestTestCommand() {}
/**
* This is a virtual constructor for the command.
*/
virtual cmCommand* Clone()
{