summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorZach Mullen <zach.mullen@kitware.com>2010-03-16 15:33:55 -0400
committerZach Mullen <zach.mullen@kitware.com>2010-03-17 11:04:13 -0400
commit0ba9d041174f593509c44f84e0e70fafc6c0edc0 (patch)
treee14112a165cafec052faf1846d97a47acdb612b9 /Source
parentbd0b37ea3d5733d087b1498a20e2b87d7f537a9f (diff)
downloadcmake-0ba9d041174f593509c44f84e0e70fafc6c0edc0.tar.gz
Add the --stop-time argument
Unit test and script hook for STOP_TIME
Diffstat (limited to 'Source')
-rw-r--r--Source/CTest/cmCTestRunTest.cxx54
-rw-r--r--Source/CTest/cmCTestRunTest.h4
-rw-r--r--Source/CTest/cmCTestTestCommand.cxx5
-rw-r--r--Source/CTest/cmCTestTestCommand.h7
-rw-r--r--Source/cmCTest.cxx42
-rw-r--r--Source/cmCTest.h7
-rw-r--r--Source/ctest.cxx4
7 files changed, 118 insertions, 5 deletions
diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx
index 659cb73e5f..94ccffe681 100644
--- a/Source/CTest/cmCTestRunTest.cxx
+++ b/Source/CTest/cmCTestRunTest.cxx
@@ -14,6 +14,7 @@
#include "cmCTestMemCheckHandler.h"
#include "cmCTest.h"
#include "cmSystemTools.h"
+#include "cm_curl.h"
#include <cm_zlib.h>
#include <cmsys/Base64.h>
@@ -441,7 +442,7 @@ bool cmCTestRunTest::StartTest(size_t total)
}
this->StartTime = this->CTest->CurrentTime();
- return this->CreateProcess(this->TestProperties->Timeout,
+ return this->ForkProcess(this->ResolveTimeout(),
&this->TestProperties->Environment);
}
@@ -518,7 +519,56 @@ void cmCTestRunTest::DartProcessing()
}
//----------------------------------------------------------------------
-bool cmCTestRunTest::CreateProcess(double testTimeOut,
+double cmCTestRunTest::ResolveTimeout()
+{
+ double timeout = this->TestProperties->Timeout;
+
+ if(this->CTest->GetStopTime() == "")
+ {
+ return timeout;
+ }
+ struct tm* lctime;
+ time_t current_time = time(0);
+ lctime = gmtime(&current_time);
+ int gm_hour = lctime->tm_hour;
+ lctime = localtime(&current_time);
+ int local_hour = lctime->tm_hour;
+
+ int timezone = (local_hour - gm_hour) * 100;
+ char buf[1024];
+ // add todays year day and month to the time in str because
+ // curl_getdate no longer assumes the day is today
+ sprintf(buf, "%d%02d%02d %s %+05i",
+ lctime->tm_year + 1900,
+ lctime->tm_mon + 1,
+ lctime->tm_mday,
+ this->CTest->GetStopTime().c_str(),
+ timezone);
+
+ time_t stop_time = curl_getdate(buf, &current_time);
+ if(stop_time == -1)
+ {
+ return timeout;
+ }
+
+ //the stop time refers to the next day
+ if(this->CTest->NextDayStopTime)
+ {
+ stop_time += 24*60*60;
+ }
+ double stop_timeout = stop_time - current_time;
+
+ if(stop_timeout <= 0)
+ {
+ cmCTestLog(this->CTest, ERROR_MESSAGE, "The stop time has been passed. "
+ "Exiting ctest." << std::endl);
+ exit(-1);
+ }
+ return timeout == 0 ? stop_timeout : min(timeout, stop_timeout);
+}
+
+//----------------------------------------------------------------------
+bool cmCTestRunTest::ForkProcess(double testTimeOut,
std::vector<std::string>* environment)
{
this->TestProcess = new cmProcess;
diff --git a/Source/CTest/cmCTestRunTest.h b/Source/CTest/cmCTestRunTest.h
index 1e4c1ccc52..14fa2e5a99 100644
--- a/Source/CTest/cmCTestRunTest.h
+++ b/Source/CTest/cmCTestRunTest.h
@@ -59,7 +59,9 @@ public:
private:
void DartProcessing();
void ExeNotFound(std::string exe);
- bool CreateProcess(double testTimeOut,
+ // Figures out a final timeout which is min(STOP_TIME, NOW+TIMEOUT)
+ double ResolveTimeout();
+ bool ForkProcess(double testTimeOut,
std::vector<std::string>* environment);
void WriteLogOutputTop(size_t completed, size_t total);
//Run post processing of the process output for MemCheck
diff --git a/Source/CTest/cmCTestTestCommand.cxx b/Source/CTest/cmCTestTestCommand.cxx
index b0adf224f1..5aee035c79 100644
--- a/Source/CTest/cmCTestTestCommand.cxx
+++ b/Source/CTest/cmCTestTestCommand.cxx
@@ -25,6 +25,7 @@ cmCTestTestCommand::cmCTestTestCommand()
this->Arguments[ctt_INCLUDE_LABEL] = "INCLUDE_LABEL";
this->Arguments[ctt_PARALLEL_LEVEL] = "PARALLEL_LEVEL";
this->Arguments[ctt_SCHEDULE_RANDOM] = "SCHEDULE_RANDOM";
+ this->Arguments[ctt_STOP_TIME] = "STOP_TIME";
this->Arguments[ctt_LAST] = 0;
this->Last = ctt_LAST;
}
@@ -98,6 +99,10 @@ cmCTestGenericHandler* cmCTestTestCommand::InitializeHandler()
handler->SetOption("ScheduleRandom",
this->Values[ctt_SCHEDULE_RANDOM]);
}
+ if(this->Values[ctt_STOP_TIME])
+ {
+ this->CTest->SetStopTime(this->Values[ctt_STOP_TIME]);
+ }
return handler;
}
diff --git a/Source/CTest/cmCTestTestCommand.h b/Source/CTest/cmCTestTestCommand.h
index 12314dfe63..c6fd6314cb 100644
--- a/Source/CTest/cmCTestTestCommand.h
+++ b/Source/CTest/cmCTestTestCommand.h
@@ -62,7 +62,8 @@ public:
" [EXCLUDE_LABEL exclude regex] \n"
" [INCLUDE_LABEL label regex] \n"
" [PARALLEL_LEVEL level] \n"
- " [SCHEDULE_RANDOM on]) \n"
+ " [SCHEDULE_RANDOM on] \n"
+ " [STOP_TIME time of day]) \n"
"Tests the given build directory and stores results in Test.xml. The "
"second argument is a variable that will hold value. Optionally, "
"you can specify the starting test number START, the ending test number "
@@ -73,7 +74,8 @@ public:
"property LABEL. PARALLEL_LEVEL should be set to a positive number "
"representing the number of tests to be run in parallel. "
"SCHEDULE_RANDOM will launch tests in a random order, and is "
- "typically used to detect implicit test dependencies."
+ "typically used to detect implicit test dependencies. STOP_TIME is the "
+ "time of day at which the tests should all stop running."
"\n"
CTEST_COMMAND_APPEND_OPTION_DOCS;
}
@@ -96,6 +98,7 @@ protected:
ctt_INCLUDE_LABEL,
ctt_PARALLEL_LEVEL,
ctt_SCHEDULE_RANDOM,
+ ctt_STOP_TIME,
ctt_LAST
};
};
diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx
index e417e1beb3..c6a38493b4 100644
--- a/Source/cmCTest.cxx
+++ b/Source/cmCTest.cxx
@@ -314,6 +314,8 @@ cmCTest::cmCTest()
this->CompressXMLFiles = false;
this->CTestConfigFile = "";
this->ScheduleType = "";
+ this->StopTime = "";
+ this->NextDayStopTime = false;
this->OutputLogFile = 0;
this->OutputLogFileLastTag = -1;
this->SuppressUpdatingCTestConfiguration = false;
@@ -1881,6 +1883,12 @@ void cmCTest::HandleCommandLineArguments(size_t &i,
double timeout = (double)atof(args[i].c_str());
this->GlobalTimeout = timeout;
}
+
+ if(this->CheckArgument(arg, "--stop-time") && i < args.size() - 1)
+ {
+ i++;
+ this->SetStopTime(args[i]);
+ }
if(this->CheckArgument(arg, "-C", "--build-config") &&
i < args.size() - 1)
@@ -2335,6 +2343,13 @@ void cmCTest::SetNotesFiles(const char* notes)
}
//----------------------------------------------------------------------
+void cmCTest::SetStopTime(std::string time)
+{
+ this->StopTime = time;
+ this->DetermineNextDayStop();
+}
+
+//----------------------------------------------------------------------
int cmCTest::ReadCustomConfigurationFileTree(const char* dir, cmMakefile* mf)
{
bool found = false;
@@ -2536,6 +2551,33 @@ void cmCTest::EmptyCTestConfiguration()
}
//----------------------------------------------------------------------
+void cmCTest::DetermineNextDayStop()
+{
+ struct tm* lctime;
+ time_t current_time = time(0);
+ lctime = gmtime(&current_time);
+ int gm_hour = lctime->tm_hour;
+ lctime = localtime(&current_time);
+ int local_hour = lctime->tm_hour;
+
+ int timezone = (local_hour - gm_hour) * 100;
+ char buf[1024];
+ sprintf(buf, "%d%02d%02d %s %+05i",
+ lctime->tm_year + 1900,
+ lctime->tm_mon + 1,
+ lctime->tm_mday,
+ this->StopTime.c_str(),
+ timezone);
+
+ time_t stop_time = curl_getdate(buf, &current_time);
+
+ if(stop_time < current_time)
+ {
+ this->NextDayStopTime = true;
+ }
+}
+
+//----------------------------------------------------------------------
void cmCTest::SetCTestConfiguration(const char *name, const char* value)
{
cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, "SetCTestConfiguration:"
diff --git a/Source/cmCTest.h b/Source/cmCTest.h
index adf359c7f7..4b6698544e 100644
--- a/Source/cmCTest.h
+++ b/Source/cmCTest.h
@@ -214,6 +214,9 @@ public:
std::string GetCDashVersion();
+ std::string GetStopTime() { return this->StopTime; }
+ void SetStopTime(std::string time);
+
//Used for parallel ctest job scheduling
std::string GetScheduleType() { return this->ScheduleType; }
void SetScheduleType(std::string type) { this->ScheduleType = type; }
@@ -403,6 +406,8 @@ public:
private:
std::string ConfigType;
std::string ScheduleType;
+ std::string StopTime;
+ bool NextDayStopTime;
bool Verbose;
bool ExtraVerbose;
bool ProduceXML;
@@ -420,6 +425,8 @@ private:
int GenerateNotesFile(const char* files);
+ void DetermineNextDayStop();
+
// these are helper classes
typedef std::map<cmStdString,cmCTestGenericHandler*> t_TestingHandlers;
t_TestingHandlers TestingHandlers;
diff --git a/Source/ctest.cxx b/Source/ctest.cxx
index c9b875dcbb..24921c428f 100644
--- a/Source/ctest.cxx
+++ b/Source/ctest.cxx
@@ -218,6 +218,10 @@ static const char * cmDocumentationOptions[][3] =
{"--timeout <seconds>", "Set a global timeout on all tests.",
"This option will set a global timeout on all tests that do not already "
"have a timeout set on them."},
+ {"--stop-time <time>", "Set a time at which all tests should stop running.",
+ "Set a real time of day at which all tests should timeout. Example: "
+ "7:00:00 -0400. Any time format understood by the curl date parser is "
+ "accepted. Local time is assumed if no timezone is specified."},
{"--http1.0", "Submit using HTTP 1.0.",
"This option will force CTest to use HTTP 1.0 to submit files to the "
"dashboard, instead of HTTP 1.1."},