summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorZach Mullen <zach.mullen@kitware.com>2010-06-03 10:34:34 -0400
committerZach Mullen <zach.mullen@kitware.com>2010-06-03 10:34:34 -0400
commite525649a4e9f2578c41593b56f9af4b4b7719984 (patch)
tree46092e3926a2ff9bee3a2038f495fc0992e8635f /Source
parent7f619608d50cabee8718d78427d560531a3b1ea1 (diff)
downloadcmake-e525649a4e9f2578c41593b56f9af4b4b7719984.tar.gz
Checksums on CTest submit files, and retry timed out submissions.
Diffstat (limited to 'Source')
-rw-r--r--Source/CTest/cmCTestSubmitCommand.cxx27
-rw-r--r--Source/CTest/cmCTestSubmitCommand.h6
-rw-r--r--Source/CTest/cmCTestSubmitHandler.cxx170
-rw-r--r--Source/CTest/cmCTestSubmitHandler.h1
4 files changed, 185 insertions, 19 deletions
diff --git a/Source/CTest/cmCTestSubmitCommand.cxx b/Source/CTest/cmCTestSubmitCommand.cxx
index d1226da1f1..6a45d58825 100644
--- a/Source/CTest/cmCTestSubmitCommand.cxx
+++ b/Source/CTest/cmCTestSubmitCommand.cxx
@@ -147,6 +147,11 @@ cmCTestGenericHandler* cmCTestSubmitCommand::InitializeHandler()
static_cast<cmCTestSubmitHandler*>(handler)->SelectParts(this->Parts);
}
+ static_cast<cmCTestSubmitHandler*>(handler)->SetOption("RetryTime",
+ this->RetryDelay.c_str());
+ static_cast<cmCTestSubmitHandler*>(handler)->SetOption("RetryCount",
+ this->RetryCount.c_str());
+
return handler;
}
@@ -169,6 +174,18 @@ bool cmCTestSubmitCommand::CheckArgumentKeyword(std::string const& arg)
return true;
}
+ if(arg == "RETRY_COUNT")
+ {
+ this->ArgumentDoing = ArgumentDoingRetryCount;
+ return true;
+ }
+
+ if(arg == "RETRY_DELAY")
+ {
+ this->ArgumentDoing = ArgumentDoingRetryDelay;
+ return true;
+ }
+
// Look for other arguments.
return this->Superclass::CheckArgumentKeyword(arg);
}
@@ -213,6 +230,16 @@ bool cmCTestSubmitCommand::CheckArgumentValue(std::string const& arg)
return true;
}
+ if(this->ArgumentDoing == ArgumentDoingRetryCount)
+ {
+ this->RetryCount = arg;
+ }
+
+ if(this->ArgumentDoing == ArgumentDoingRetryDelay)
+ {
+ this->RetryDelay = arg;
+ }
+
// Look for other arguments.
return this->Superclass::CheckArgumentValue(arg);
}
diff --git a/Source/CTest/cmCTestSubmitCommand.h b/Source/CTest/cmCTestSubmitCommand.h
index ccaef7e36d..14dfa37c06 100644
--- a/Source/CTest/cmCTestSubmitCommand.h
+++ b/Source/CTest/cmCTestSubmitCommand.h
@@ -29,6 +29,8 @@ public:
{
this->PartsMentioned = false;
this->FilesMentioned = false;
+ this->RetryCount = "";
+ this->RetryDelay = "";
}
/**
@@ -92,6 +94,8 @@ protected:
{
ArgumentDoingParts = Superclass::ArgumentDoingLast1,
ArgumentDoingFiles,
+ ArgumentDoingRetryDelay,
+ ArgumentDoingRetryCount,
ArgumentDoingLast2
};
@@ -99,6 +103,8 @@ protected:
std::set<cmCTest::Part> Parts;
bool FilesMentioned;
cmCTest::SetOfStrings Files;
+ std::string RetryCount;
+ std::string RetryDelay;
};
diff --git a/Source/CTest/cmCTestSubmitHandler.cxx b/Source/CTest/cmCTestSubmitHandler.cxx
index 7b4f38b2c9..fca05aca11 100644
--- a/Source/CTest/cmCTestSubmitHandler.cxx
+++ b/Source/CTest/cmCTestSubmitHandler.cxx
@@ -15,6 +15,7 @@
#include "cmVersion.h"
#include "cmGeneratedFileStream.h"
#include "cmCTest.h"
+#include "cmXMLParser.h"
#include <cmsys/Process.h>
#include <cmsys/Base64.h>
@@ -31,6 +32,80 @@
typedef std::vector<char> cmCTestSubmitHandlerVectorOfChar;
+//----------------------------------------------------------------------------
+class cmCTestSubmitHandler::ResponseParser: public cmXMLParser
+{
+public:
+ ResponseParser() { this->Status = STATUS_OK; }
+ ~ResponseParser() {}
+
+public:
+
+ enum StatusType
+ {
+ STATUS_OK,
+ STATUS_WARNING,
+ STATUS_ERROR
+ };
+
+ StatusType Status;
+ std::string CDashVersion;
+ std::string Filename;
+ std::string MD5;
+ std::string Message;
+
+private:
+ std::string CurrentValue;
+ std::string CurrentTag;
+
+ virtual void StartElement(const char* name, const char** atts)
+ {
+ this->CurrentValue = "";
+ if(strcmp(name, "cdash") == 0)
+ {
+ this->CDashVersion = this->FindAttribute(atts, "version");
+ }
+ }
+
+ virtual void CharacterDataHandler(const char* data, int length)
+ {
+ this->CurrentValue.insert(this->CurrentValue.end(), data, data+length);
+ }
+
+ virtual void EndElement(const char* name)
+ {
+ if(strcmp(name, "status") == 0)
+ {
+ this->CurrentValue = cmSystemTools::UpperCase(this->CurrentValue);
+ if(this->CurrentValue == "OK" || this->CurrentValue == "SUCCESS")
+ {
+ this->Status = STATUS_OK;
+ }
+ else if(this->CurrentValue == "WARNING")
+ {
+ this->Status = STATUS_WARNING;
+ }
+ else
+ {
+ this->Status = STATUS_ERROR;
+ }
+ }
+ else if(strcmp(name, "filename") == 0)
+ {
+ this->Filename = this->CurrentValue;
+ }
+ else if(strcmp(name, "md5") == 0)
+ {
+ this->MD5 = this->CurrentValue;
+ }
+ else if(strcmp(name, "message") == 0)
+ {
+ this->Message = this->CurrentValue;
+ }
+ }
+};
+
+
static size_t
cmCTestSubmitHandlerWriteMemoryCallback(void *ptr, size_t size, size_t nmemb,
void *data)
@@ -367,6 +442,13 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(const cmStdString& localprefix,
= url + ((url.find("?",0) == cmStdString::npos) ? "?" : "&")
+ "FileName=" + ofile;
+ char md5[33];
+ cmSystemTools::ComputeFileMD5(local_file.c_str(), md5);
+ md5[32] = 0;
+ std::stringstream md5string;
+ md5string << "&MD5=" << md5;
+ upload_as += md5string.str();
+
struct stat st;
if ( ::stat(local_file.c_str(), &st) )
{
@@ -382,7 +464,6 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(const cmStdString& localprefix,
<< local_file.c_str() << " to "
<< upload_as.c_str() << " Size: " << st.st_size << std::endl);
-
// specify target
::curl_easy_setopt(curl,CURLOPT_URL, upload_as.c_str());
@@ -411,6 +492,47 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP(const cmStdString& localprefix,
// Now run off and do what you've been told!
res = ::curl_easy_perform(curl);
+ // If we time out or operation is too slow, wait and retry
+ if(res == CURLE_OPERATION_TIMEOUTED)
+ {
+ std::string retryTime = this->GetOption("RetryTime") == NULL ?
+ "" : this->GetOption("RetryTime");
+ std::string retryCount = this->GetOption("RetryCount") == NULL ?
+ "" : this->GetOption("RetryCount");
+
+ int time = retryTime == "" ? atoi(this->CTest->GetCTestConfiguration(
+ "CTestRetryTime").c_str()) : atoi(retryTime.c_str());
+ int count = retryCount == "" ? atoi(this->CTest->GetCTestConfiguration(
+ "CTestRetryCount").c_str()) : atoi(retryCount.c_str());
+
+ for(int i = 0; i < count; i++)
+ {
+ cmCTestLog(this->CTest, HANDLER_OUTPUT,
+ " Connection timed out, waiting " << time << " seconds...\n");
+
+ double stop = cmSystemTools::GetTime() + time;
+ while(cmSystemTools::GetTime() < stop) {} //wait <time> seconds
+
+ cmCTestLog(this->CTest, HANDLER_OUTPUT,
+ " Retry submission: Attempt " << (i + 1) << " of "
+ << count << std::endl);
+
+ ::fclose(ftpfile);
+ ftpfile = ::fopen(local_file.c_str(), "rb");
+ ::curl_easy_setopt(curl, CURLOPT_INFILE, ftpfile);
+
+ chunk.clear();
+ chunkDebug.clear();
+
+ res = ::curl_easy_perform(curl);
+
+ if(res != CURLE_OPERATION_TIMEDOUT)
+ {
+ break;
+ }
+ }
+ }
+
if ( chunk.size() > 0 )
{
cmCTestLog(this->CTest, DEBUG, "CURL output: ["
@@ -467,29 +589,39 @@ void cmCTestSubmitHandler
::ParseResponse(cmCTestSubmitHandlerVectorOfChar chunk)
{
std::string output = "";
+ output.append(chunk.begin(), chunk.end());
- for(cmCTestSubmitHandlerVectorOfChar::iterator i = chunk.begin();
- i != chunk.end(); ++i)
- {
- output += *i;
- }
- output = cmSystemTools::UpperCase(output);
-
- if(output.find("WARNING") != std::string::npos)
- {
- this->HasWarnings = true;
- }
- if(output.find("ERROR") != std::string::npos)
+ if(output.find("<cdash") != output.npos)
{
- this->HasErrors = true;
+ ResponseParser parser;
+ parser.Parse(output.c_str());
+
+ if(parser.Status != ResponseParser::STATUS_OK)
+ {
+ this->HasErrors = true;
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, " Submission failed: " <<
+ parser.Message << std::endl);
+ return;
+ }
}
-
- if(this->HasWarnings || this->HasErrors)
+ else
{
- cmCTestLog(this->CTest, HANDLER_OUTPUT, " Server Response:\n" <<
- cmCTestLogWrite(&*chunk.begin(), chunk.size()) << "\n");
+ output = cmSystemTools::UpperCase(output);
+ if(output.find("WARNING") != std::string::npos)
+ {
+ this->HasWarnings = true;
+ }
+ if(output.find("ERROR") != std::string::npos)
+ {
+ this->HasErrors = true;
+ }
+
+ if(this->HasWarnings || this->HasErrors)
+ {
+ cmCTestLog(this->CTest, HANDLER_OUTPUT, " Server Response:\n" <<
+ cmCTestLogWrite(&*chunk.begin(), chunk.size()) << "\n");
+ }
}
-
}
//----------------------------------------------------------------------------
diff --git a/Source/CTest/cmCTestSubmitHandler.h b/Source/CTest/cmCTestSubmitHandler.h
index 8b011ea191..e7755b138b 100644
--- a/Source/CTest/cmCTestSubmitHandler.h
+++ b/Source/CTest/cmCTestSubmitHandler.h
@@ -79,6 +79,7 @@ private:
std::string GetSubmitResultsPrefix();
+ class ResponseParser;
cmStdString HTTPProxy;
int HTTPProxyType;
cmStdString HTTPProxyAuth;