Fix issue #10060 - add APPEND arg to ctest_start command.

If APPEND is given to ctest_start, it will read the tag from the current existing Testing/TAG file rather than creating a new one based on the current time stamp. This allows a developer to run several dashboard scripts in a row, all of which will share the same tag/stamp/buildid when they finally get submitted to CDash. Now you can split the running of build phases and test phases for the same dashboard row into multiple scripts.
This commit is contained in:
David Cole 2009-12-29 14:38:31 -05:00
parent 5ce7e35960
commit aad15c3abf
5 changed files with 118 additions and 58 deletions

View File

@ -17,6 +17,11 @@
#include "cmCTestVC.h"
#include "cmGeneratedFileStream.h"
cmCTestStartCommand::cmCTestStartCommand()
{
this->CreateNewTag = true;
}
bool cmCTestStartCommand
::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
{
@ -44,6 +49,15 @@ bool cmCTestStartCommand
}
}
if (cnt < args.size())
{
if (args[cnt] == "APPEND")
{
cnt ++;
this->CreateNewTag = false;
}
}
if ( cnt < args.size() )
{
src_dir = args[cnt].c_str();

View File

@ -23,7 +23,7 @@ class cmCTestStartCommand : public cmCTestCommand
{
public:
cmCTestStartCommand() {}
cmCTestStartCommand();
/**
* This is a virtual constructor for the command.
@ -33,6 +33,7 @@ public:
cmCTestStartCommand* ni = new cmCTestStartCommand;
ni->CTest = this->CTest;
ni->CTestScriptHandler = this->CTestScriptHandler;
ni->CreateNewTag = this->CreateNewTag;
return ni;
}
@ -43,6 +44,14 @@ public:
virtual bool InitialPass(std::vector<std::string> const& args,
cmExecutionStatus &status);
/**
* Will this invocation of ctest_start create a new TAG file?
*/
bool ShouldCreateNewTag()
{
return this->CreateNewTag;
}
/**
* The name of the command as specified in CMakeList.txt.
*/
@ -62,18 +71,21 @@ public:
virtual const char* GetFullDocumentation()
{
return
" ctest_start(Model [TRACK <track>] [source [binary]])\n"
" ctest_start(Model [TRACK <track>] [APPEND] [source [binary]])\n"
"Starts the testing for a given model. The command should be called "
"after the binary directory is initialized. If the 'source' and "
"'binary' directory are not specified, it reads the "
"CTEST_SOURCE_DIRECTORY and CTEST_BINARY_DIRECTORY. If the track is "
"specified, the submissions will go to the specified track.";
"specified, the submissions will go to the specified track. "
"If APPEND is used, the existing TAG is used rather than "
"creating a new one based on the current time stamp.";
}
cmTypeMacro(cmCTestStartCommand, cmCTestCommand);
private:
bool InitialCheckout(std::ostream& ofs, std::string const& sourceDir);
bool CreateNewTag;
};

View File

@ -402,7 +402,7 @@ cmCTest::Part cmCTest::GetPartFromName(const char* name)
}
//----------------------------------------------------------------------
int cmCTest::Initialize(const char* binary_dir, bool script)
int cmCTest::Initialize(const char* binary_dir, cmCTestStartCommand* command)
{
cmCTestLog(this, DEBUG, "Here: " << __LINE__ << std::endl);
if(!this->InteractiveDebugMode)
@ -453,6 +453,8 @@ int cmCTest::Initialize(const char* binary_dir, bool script)
if ( this->ProduceXML )
{
// Verify "Testing" directory exists:
//
std::string testingDir = this->BinaryDir + "/Testing";
if ( cmSystemTools::FileExists(testingDir.c_str()) )
{
@ -472,73 +474,101 @@ int cmCTest::Initialize(const char* binary_dir, bool script)
return 0;
}
}
// Create new "TAG" file or read existing one:
//
std::string tagfile = testingDir + "/TAG";
std::ifstream tfin(tagfile.c_str());
std::string tag;
time_t tctime = time(0);
if ( this->TomorrowTag )
if (command->ShouldCreateNewTag())
{
tctime += ( 24 * 60 * 60 );
}
struct tm *lctime = gmtime(&tctime);
if ( tfin && cmSystemTools::GetLineFromStream(tfin, tag) )
{
int year = 0;
int mon = 0;
int day = 0;
int hour = 0;
int min = 0;
sscanf(tag.c_str(), "%04d%02d%02d-%02d%02d",
&year, &mon, &day, &hour, &min);
if ( year != lctime->tm_year + 1900 ||
mon != lctime->tm_mon+1 ||
day != lctime->tm_mday )
time_t tctime = time(0);
if ( this->TomorrowTag )
{
tag = "";
tctime += ( 24 * 60 * 60 );
}
std::string tagmode;
if ( cmSystemTools::GetLineFromStream(tfin, tagmode) )
struct tm *lctime = gmtime(&tctime);
if ( tfin && cmSystemTools::GetLineFromStream(tfin, tag) )
{
if (tagmode.size() > 4 && !this->Parts[PartStart])
int year = 0;
int mon = 0;
int day = 0;
int hour = 0;
int min = 0;
sscanf(tag.c_str(), "%04d%02d%02d-%02d%02d",
&year, &mon, &day, &hour, &min);
if ( year != lctime->tm_year + 1900 ||
mon != lctime->tm_mon+1 ||
day != lctime->tm_mday )
{
this->TestModel = cmCTest::GetTestModelFromString(tagmode.c_str());
tag = "";
}
std::string tagmode;
if ( cmSystemTools::GetLineFromStream(tfin, tagmode) )
{
if (tagmode.size() > 4 && !this->Parts[PartStart])
{
this->TestModel = cmCTest::GetTestModelFromString(tagmode.c_str());
}
}
tfin.close();
}
if (tag.size() == 0 || (0 != command) || this->Parts[PartStart])
{
cmCTestLog(this, DEBUG, "TestModel: " << this->GetTestModelString()
<< std::endl);
cmCTestLog(this, DEBUG, "TestModel: " << this->TestModel << std::endl);
if ( this->TestModel == cmCTest::NIGHTLY )
{
lctime = this->GetNightlyTime(
this->GetCTestConfiguration("NightlyStartTime"), this->TomorrowTag);
}
char datestring[100];
sprintf(datestring, "%04d%02d%02d-%02d%02d",
lctime->tm_year + 1900,
lctime->tm_mon+1,
lctime->tm_mday,
lctime->tm_hour,
lctime->tm_min);
tag = datestring;
std::ofstream ofs(tagfile.c_str());
if ( ofs )
{
ofs << tag << std::endl;
ofs << this->GetTestModelString() << std::endl;
}
ofs.close();
if ( 0 == command )
{
cmCTestLog(this, OUTPUT, "Create new tag: " << tag << " - "
<< this->GetTestModelString() << std::endl);
}
}
tfin.close();
}
if (tag.size() == 0 || script || this->Parts[PartStart])
else
{
cmCTestLog(this, DEBUG, "TestModel: " << this->GetTestModelString()
<< std::endl);
cmCTestLog(this, DEBUG, "TestModel: " << this->TestModel << std::endl);
if ( this->TestModel == cmCTest::NIGHTLY )
if ( tfin )
{
lctime = this->GetNightlyTime(
this->GetCTestConfiguration("NightlyStartTime"), this->TomorrowTag);
cmSystemTools::GetLineFromStream(tfin, tag);
tfin.close();
}
char datestring[100];
sprintf(datestring, "%04d%02d%02d-%02d%02d",
lctime->tm_year + 1900,
lctime->tm_mon+1,
lctime->tm_mday,
lctime->tm_hour,
lctime->tm_min);
tag = datestring;
std::ofstream ofs(tagfile.c_str());
if ( ofs )
if ( tag.empty() )
{
ofs << tag << std::endl;
ofs << this->GetTestModelString() << std::endl;
}
ofs.close();
if ( !script )
{
cmCTestLog(this, OUTPUT, "Create new tag: " << tag << " - "
<< this->GetTestModelString() << std::endl);
cmCTestLog(this, ERROR_MESSAGE,
"Cannot read existing TAG file in " << testingDir
<< std::endl);
return 0;
}
cmCTestLog(this, OUTPUT, " Use existing tag: " << tag << " - "
<< this->GetTestModelString() << std::endl);
}
this->CurrentTag = tag;
}
return 1;
}
@ -596,7 +626,7 @@ bool cmCTest::InitializeFromCommand(cmCTestStartCommand* command)
}
}
if ( !this->Initialize(bld_dir.c_str(), true) )
if ( !this->Initialize(bld_dir.c_str(), command) )
{
return false;
}
@ -2206,7 +2236,7 @@ int cmCTest::Run(std::vector<std::string> &args, std::string* output)
it->second->SetSubmitIndex(this->SubmitIndex);
}
std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
if(!this->Initialize(cwd.c_str(), false))
if(!this->Initialize(cwd.c_str(), 0))
{
res = 12;
cmCTestLog(this, ERROR_MESSAGE, "Problem initializing the dashboard."

View File

@ -475,14 +475,14 @@ private:
void BlockTestErrorDiagnostics();
/**
* Initialize a dashboard run in the given build tree. The "script"
* argument is true when running from a command-driven (ctest_start)
* dashboard script, and false when running from the CTest command
* Initialize a dashboard run in the given build tree. The "command"
* argument is non-NULL when running from a command-driven (ctest_start)
* dashboard script, and NULL when running from the CTest command
* line. Note that a declarative dashboard script does not actually
* call this method because it sets CTEST_COMMAND to drive a build
* through the ctest command line.
*/
int Initialize(const char* binary_dir, bool script);
int Initialize(const char* binary_dir, cmCTestStartCommand* command);
//! parse the option after -D and convert it into the appropriate steps
bool AddTestsForDashboardType(std::string &targ);

View File

@ -45,3 +45,7 @@ CTEST_COVERAGE(BUILD "${CTEST_BINARY_DIRECTORY}" @ctest_coverage_labels_args@ RE
# ok to call ctest_submit - still avoids network activity because there is
# not a valid drop location given above...
CTEST_SUBMIT(RETURN_VALUE res)
# Add coverage for the new APPEND arg to ctest_start:
#
CTEST_START(Experimental APPEND)