From 3d84afe571f03f0f8406a4af95746877b5ee9267 Mon Sep 17 00:00:00 2001 From: Andy Cedilnik Date: Mon, 18 Jul 2005 11:46:45 -0400 Subject: ENH: Several improvements and cleanups: 1. Add long command line arguments for every argument 2. Add a way to overwrite CTest configuration by providing --overwrite TimeOut=10 3. Improve argument parsing. 4. Add submit index argument --- Modules/Dart.cmake | 26 +++++--- Source/cmCTest.cxx | 139 +++++++++++++++++++++++++++++++---------- Source/cmCTest.h | 9 +++ Source/ctest.cxx | 36 +++++++---- Tests/CTestTest2/test.cmake.in | 9 ++- 5 files changed, 162 insertions(+), 57 deletions(-) diff --git a/Modules/Dart.cmake b/Modules/Dart.cmake index e577828..1acd2d8 100644 --- a/Modules/Dart.cmake +++ b/Modules/Dart.cmake @@ -28,25 +28,31 @@ IF(BUILD_TESTING) ELSE(EXISTS ${PROJECT_SOURCE_DIR}/DartConfig.cmake) # Dashboard is opened for submissions for a 24 hour period starting at # the specified NIGHTLY_START_TIME. Time is specified in 24 hour format. - SET (NIGHTLY_START_TIME "00:00:00 EDT") + MACRO(SET_IF_NOT_SET var val) + IF(NOT "${${var}}") + SET("${var}" "${val}") + ENDIF(NOT "${${var}}") + ENDMACRO(SET_IF_NOT_SET) + + SET_IF_NOT_SET (NIGHTLY_START_TIME "00:00:00 EDT") # Dart server to submit results (used by client) # There should be an option to specify submit method, but I will leave it # commented until we decide what to do with it. # SET(DROP_METHOD "http" CACHE STRING "Set the CTest submit method. Valid options are http and ftp") IF(DROP_METHOD MATCHES http) - SET (DROP_SITE "public.kitware.com") - SET (DROP_LOCATION "/cgi-bin/HTTPUploadDartFile.cgi") + SET_IF_NOT_SET (DROP_SITE "public.kitware.com") + SET_IF_NOT_SET (DROP_LOCATION "/cgi-bin/HTTPUploadDartFile.cgi") ELSE(DROP_METHOD MATCHES http) - SET (DROP_SITE "public.kitware.com") - SET (DROP_LOCATION "/incoming") - SET (DROP_SITE_USER "anonymous") - SET (DROP_SITE_PASSWORD "random@ringworld") - SET (DROP_SITE_MODE "active") + SET_IF_NOT_SET (DROP_SITE "public.kitware.com") + SET_IF_NOT_SET (DROP_LOCATION "/incoming") + SET_IF_NOT_SET (DROP_SITE_USER "anonymous") + SET_IF_NOT_SET (DROP_SITE_PASSWORD "random@ringworld") + SET_IF_NOT_SET (DROP_SITE_MODE "active") ENDIF(DROP_METHOD MATCHES http) - SET (TRIGGER_SITE "http://${DROP_SITE}/cgi-bin/Submit-Random-TestingResults.cgi") - SET (COMPRESS_SUBMISSION ON) + SET_IF_NOT_SET (TRIGGER_SITE "http://${DROP_SITE}/cgi-bin/Submit-Random-TestingResults.cgi") + SET_IF_NOT_SET (COMPRESS_SUBMISSION ON) # Project Home Page SET (PROJECT_URL "http://www.kitware.com") diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx index ee25fc7..a79f75b 100644 --- a/Source/cmCTest.cxx +++ b/Source/cmCTest.cxx @@ -362,7 +362,7 @@ int cmCTest::Initialize(const char* binary_dir, bool new_tag, bool verbose_tag) cmCTestLog(this, DEBUG, "TestModel: " << m_TestModel << std::endl); if ( m_TestModel == cmCTest::NIGHTLY ) { - lctime = this->GetNightlyTime(m_CTestConfiguration["NightlyStartTime"], m_TomorrowTag); + lctime = this->GetNightlyTime(this->GetCTestConfiguration("NightlyStartTime"), m_TomorrowTag); } char datestring[100]; sprintf(datestring, "%04d%02d%02d-%02d%02d", @@ -525,10 +525,10 @@ bool cmCTest::UpdateCTestConfiguration() } fin.close(); } + m_TimeOut = atoi(this->GetCTestConfiguration("TimeOut").c_str()); if ( m_ProduceXML ) { - m_TimeOut = atoi(m_CTestConfiguration["TimeOut"].c_str()); - m_CompressXMLFiles = cmSystemTools::IsOn(m_CTestConfiguration["CompressSubmission"].c_str()); + m_CompressXMLFiles = cmSystemTools::IsOn(this->GetCTestConfiguration("CompressSubmission").c_str()); } return true; } @@ -1095,10 +1095,10 @@ int cmCTest::RunTest(std::vector argv, void cmCTest::StartXML(std::ostream& ostr) { ostr << "\n" - << "GetCTestConfiguration("BuildName") << "\" BuildStamp=\"" << m_CurrentTag << "-" << this->GetTestModelString() << "\" Name=\"" - << m_CTestConfiguration["Site"] << "\" Generator=\"ctest" + << this->GetCTestConfiguration("Site") << "\" Generator=\"ctest" << cmVersion::GetCMakeVersion() << "\">" << std::endl; } @@ -1115,9 +1115,9 @@ int cmCTest::GenerateCTestNotesOutput(std::ostream& os, const cmCTest::tm_Vector cmCTest::tm_VectorOfStrings::const_iterator it; os << "\n" << " \"?>\n" - << "GetCTestConfiguration("BuildName") << "\" BuildStamp=\"" << m_CurrentTag << "-" << this->GetTestModelString() << "\" Name=\"" - << m_CTestConfiguration["Site"] << "\" Generator=\"ctest" + << this->GetCTestConfiguration("Site") << "\" Generator=\"ctest" << cmVersion::GetCMakeVersion() << "\">\n" << "" << std::endl; @@ -1188,6 +1188,43 @@ int cmCTest::GenerateNotesFile(const char* cfiles) } //---------------------------------------------------------------------- +bool cmCTest::CheckArgument(const std::string& arg, const char* varg1, const char* varg2 = 0) +{ + cmOStringStream ostr; + ostr << varg1; + if ( varg2 ) + { + ostr << ", " << varg2; + } + + size_t minlen = arg.size(); + size_t lenvarg = strlen(varg1); + if ( lenvarg < minlen ) + { + minlen = lenvarg; + } + if ( strncmp(arg.c_str(), varg1, minlen) == 0 ) + { + return true; + } + if ( ! varg2 ) + { + return false; + } + minlen = arg.size(); + lenvarg = strlen(varg2); + if ( lenvarg < minlen ) + { + minlen = lenvarg; + } + if ( strncmp(arg.c_str(), varg2, minlen) == 0 ) + { + return true; + } + return false; +} + +//---------------------------------------------------------------------- int cmCTest::Run(std::vectorconst& args, std::string* output) { this->FindRunningCMake(args[0].c_str()); @@ -1197,47 +1234,47 @@ int cmCTest::Run(std::vectorconst& args, std::string* output) for(size_t i=1; i < args.size(); ++i) { std::string arg = args[i]; - if(arg.find("--ctest-config",0) == 0 && i < args.size() - 1) + if(this->CheckArgument(arg, "--ctest-config") && i < args.size() - 1) { i++; this->m_CTestConfigFile= args[i]; } - if(arg.find("-C",0) == 0 && i < args.size() - 1) + if(this->CheckArgument(arg, "-C", "--build-config") && i < args.size() - 1) { i++; this->m_ConfigType = args[i]; cmSystemTools::ReplaceString(this->m_ConfigType, ".\\", ""); } - if( arg.find("--debug",0) == 0 ) + if(this->CheckArgument(arg, "--debug")) { this->m_Debug = true; } - if( arg.find("--show-line-numbers",0) == 0 ) + if(this->CheckArgument(arg, "--show-line-numbers")) { this->m_ShowLineNumbers = true; } - if( arg.find("-Q",0) == 0 || arg.find("--quiet",0) == 0 ) + if(this->CheckArgument(arg, "-Q", "--quiet")) { this->m_Quiet = true; } - if( arg.find("-V",0) == 0 || arg.find("--verbose",0) == 0 ) + if(this->CheckArgument(arg, "-V", "--verbose")) { this->m_Verbose = true; } - if( arg.find("-VV",0) == 0 || arg.find("--extra-verbose",0) == 0 ) + if(this->CheckArgument(arg, "-VV", "--extra-verbose")) { this->m_ExtraVerbose = true; this->m_Verbose = true; } - if( arg.find("-N",0) == 0 || arg.find("--show-only",0) == 0 ) + if(this->CheckArgument(arg, "-N", "--show-only")) { this->m_ShowOnly = true; } - if( arg.find("-S",0) == 0 && i < args.size() - 1 ) + if(this->CheckArgument(arg, "-S", "--script") && i < args.size() - 1 ) { this->m_RunConfigurationScript = true; i++; @@ -1245,26 +1282,35 @@ int cmCTest::Run(std::vectorconst& args, std::string* output) ch->AddConfigurationScript(args[i].c_str()); } - if( ( arg.find("-O",0) == 0 || arg.find("--output-log") == 0 ) && i < args.size() - 1 ) + if(this->CheckArgument(arg, "-O", "--output-log") && i < args.size() - 1 ) { i++; this->SetOutputLogFileName(args[i].c_str()); } - if( arg.find("--tomorrow-tag",0) == 0 ) + if(this->CheckArgument(arg, "--tomorrow-tag")) { m_TomorrowTag = true; } - if( arg.find("--force-new-ctest-process",0) == 0 ) + if(this->CheckArgument(arg, "--force-new-ctest-process")) { m_ForceNewCTestProcess = true; } - if( arg.find("--interactive-debug-mode",0) == 0 && i < args.size() - 1 ) + if(this->CheckArgument(arg, "--interactive-debug-mode") && i < args.size() - 1 ) { i++; m_InteractiveDebugMode = cmSystemTools::IsOn(args[i].c_str()); } - if( arg.find("-D",0) == 0 && i < args.size() - 1 ) + if(this->CheckArgument(arg, "--submit-index") && i < args.size() - 1 ) + { + i++; + m_SubmitIndex = atoi(args[i].c_str()); + if ( m_SubmitIndex < 0 ) + { + m_SubmitIndex = 0; + } + } + if(this->CheckArgument(arg, "-D", "--dashboard") && i < args.size() - 1 ) { this->m_ProduceXML = true; i++; @@ -1463,15 +1509,15 @@ int cmCTest::Run(std::vectorconst& args, std::string* output) } } - if( ( arg.find("-T",0) == 0 ) && - (i < args.size() -1) ) + if(this->CheckArgument(arg, "-T", "--test-action") && (i < args.size() -1) ) { this->m_ProduceXML = true; i++; if ( !this->SetTest(args[i].c_str(), false) ) { performSomeTest = false; - cmCTestLog(this, ERROR_MESSAGE, "CTest -T called with incorrect option: " << args[i].c_str() << std::endl); + cmCTestLog(this, ERROR_MESSAGE, "CTest -T called with incorrect option: " + << args[i].c_str() << std::endl); cmCTestLog(this, ERROR_MESSAGE, "Available options are:" << std::endl << " " << ctestExec << " -T all" << std::endl << " " << ctestExec << " -T start" << std::endl @@ -1486,8 +1532,7 @@ int cmCTest::Run(std::vectorconst& args, std::string* output) } } - if( ( arg.find("-M",0) == 0 || arg.find("--test-model",0) == 0 ) && - (i < args.size() -1) ) + if(this->CheckArgument(arg, "-M", "--test-model") && (i < args.size() -1) ) { i++; std::string const& str = args[i]; @@ -1514,28 +1559,33 @@ int cmCTest::Run(std::vectorconst& args, std::string* output) } } - if(arg.find("-I",0) == 0 && i < args.size() - 1) + if(this->CheckArgument(arg, "-I", "--tests-information") && i < args.size() - 1) { i++; this->GetHandler("test")->SetOption("TestsToRunInformation", args[i].c_str()); } - if(arg.find("-U",0) == 0) + if(this->CheckArgument(arg, "-U", "--union")) { this->GetHandler("test")->SetOption("UseUnion", "true"); } - if(arg.find("-R",0) == 0 && i < args.size() - 1) + if(this->CheckArgument(arg, "-R", "--tests-regex") && i < args.size() - 1) { i++; this->GetHandler("test")->SetOption("IncludeRegularExpression", args[i].c_str()); } - if(arg.find("-E",0) == 0 && i < args.size() - 1) + if(this->CheckArgument(arg, "-E", "--exclude-regex") && i < args.size() - 1) { i++; this->GetHandler("test")->SetOption("ExcludeRegularExpression", args[i].c_str()); } - if(arg.find("-A",0) == 0 && i < args.size() - 1) + if(this->CheckArgument(arg, "--overwrite") && i < args.size() - 1) + { + i++; + this->AddCTestConfigurationOverwrite(args[i].c_str()); + } + if(this->CheckArgument(arg, "-A", "--add-notes") && i < args.size() - 1) { this->m_ProduceXML = true; this->SetTest("Notes"); @@ -1543,7 +1593,7 @@ int cmCTest::Run(std::vectorconst& args, std::string* output) this->SetNotesFiles(args[i].c_str()); } // --build-and-test options - if(arg.find("--build-and-test",0) == 0 && i < args.size() - 1) + if(this->CheckArgument(arg, "--build-and-test") && i < args.size() - 1) { cmakeAndTest = true; } @@ -1566,7 +1616,6 @@ int cmCTest::Run(std::vectorconst& args, std::string* output) #endif } - if(cmakeAndTest) { m_Verbose = true; @@ -1597,6 +1646,7 @@ int cmCTest::Run(std::vectorconst& args, std::string* output) for ( it = m_TestingHandlers.begin(); it != m_TestingHandlers.end(); ++ it ) { it->second->SetVerbose(this->m_ExtraVerbose); + it->second->SetSubmitIndex(m_SubmitIndex); } this->GetHandler("script")->SetVerbose(m_Verbose); res = this->GetHandler("script")->ProcessHandler(); @@ -1609,6 +1659,7 @@ int cmCTest::Run(std::vectorconst& args, std::string* output) for ( it = m_TestingHandlers.begin(); it != m_TestingHandlers.end(); ++ it ) { it->second->SetVerbose(this->m_Verbose); + it->second->SetSubmitIndex(m_SubmitIndex); } if ( !this->Initialize(cmSystemTools::GetCurrentWorkingDirectory().c_str()) ) { @@ -1836,6 +1887,10 @@ std::string cmCTest::GetShortPathToFile(const char* cfname) //---------------------------------------------------------------------- std::string cmCTest::GetCTestConfiguration(const char *name) { + if ( m_CTestConfigurationOverwrites.find(name) != m_CTestConfigurationOverwrites.end() ) + { + return m_CTestConfigurationOverwrites[name]; + } return m_CTestConfiguration[name]; } @@ -1904,6 +1959,24 @@ void cmCTest::AddSubmitFile(const char* name) } //---------------------------------------------------------------------- +void cmCTest::AddCTestConfigurationOverwrite(const char* encstr) +{ + std::string overStr = encstr; + size_t epos = overStr.find("="); + if ( epos == overStr.npos ) + { + cmCTestLog(this, ERROR_MESSAGE, + "CTest configuration overwrite specified in the wrong format." << std::endl + << "Valid format is: --overwrite key=value" << std::endl + << "The specified was: --overwrite " << overStr.c_str() << std::endl); + return; + } + std::string key = overStr.substr(0, epos); + std::string value = overStr.substr(epos+1, overStr.npos); + m_CTestConfigurationOverwrites[key] = value; +} + +//---------------------------------------------------------------------- bool cmCTest::SetCTestConfigurationFromCMakeVariable(cmMakefile* mf, const char* dconfig, const char* cmake_var) { const char* ctvar; diff --git a/Source/cmCTest.h b/Source/cmCTest.h index 9ca2844..0a80e72 100644 --- a/Source/cmCTest.h +++ b/Source/cmCTest.h @@ -250,6 +250,10 @@ public: m_SuppressUpdatingCTestConfiguration = val; } + //! Add overwrite to ctest configuration. + // The format is key=value + void AddCTestConfigurationOverwrite(const char* encstr); + //! Create XML file that contains all the notes specified int GenerateNotesFile(const std::vector &files); @@ -315,6 +319,7 @@ private: std::string m_CTestConfigFile; tm_CTestConfigurationMap m_CTestConfiguration; + tm_CTestConfigurationMap m_CTestConfigurationOverwrites; int m_Tests[LAST_TEST]; std::string m_CurrentTag; @@ -354,6 +359,9 @@ private: ///! Find the running cmake void FindRunningCMake(const char* arg0); + //! Check if the argument is the one specified + bool CheckArgument(const std::string& arg, const char* varg1, const char* varg2 = 0); + bool m_SuppressUpdatingCTestConfiguration; bool m_Debug; @@ -364,6 +372,7 @@ private: std::set m_SubmitFiles; + int m_SubmitIndex; cmGeneratedFileStream* m_OutputLogFile; int m_OutputLogFileLastTag; diff --git a/Source/ctest.cxx b/Source/ctest.cxx index df5f4a3..46dfdac 100644 --- a/Source/ctest.cxx +++ b/Source/ctest.cxx @@ -52,13 +52,16 @@ static const cmDocumentationEntry cmDocumentationDescription[] = //---------------------------------------------------------------------------- static const cmDocumentationEntry cmDocumentationOptions[] = { - {"-C ", "Choose configuration to test.", + {"-C , --build-config ", "Choose configuration to test.", "Some CMake-generated build trees can have multiple build configurations " "in the same tree. This option can be used to specify which one should " "be tested. Example configurations are \"Debug\" and \"Release\"."}, {"-V,--verbose", "Enable verbose output from tests.", "Test output is normally suppressed and only summary information is " "displayed. This option will show all test output."}, + {"-VV,--extra-verbose", "Enable more verbose output from tests.", + "Test output is normally suppressed and only summary information is " + "displayed. This option will show even more test output."}, {"--debug", "Displaying more verbose internals of CTest.", "This feature will result in large number of output that is mostly useful " "for debugging dashboard problems."}, @@ -71,41 +74,41 @@ static const cmDocumentationEntry cmDocumentationOptions[] = {"-N,--show-only", "Disable actual execution of tests.", "This option tells ctest to list the tests that would be run but not " "actually run them. Useful in conjunction with the -R and -E options."}, - {"-R ", "Run tests matching regular expression.", + {"-R , --tests-regex ", "Run tests matching regular expression.", "This option tells ctest to run only the tests whose names match the " "given regular expression."}, - {"-E ", "Exclude tests matching regular expression.", + {"-E , --exclude-regex ", "Exclude tests matching regular expression.", "This option tells ctest to NOT run the tests whose names match the " "given regular expression."}, - {"-D ", "Execute dashboard test", + {"-D , --dashboard ", "Execute dashboard test", "This option tells ctest to perform act as a Dart client and perform " - "a dashboard test. All tests are ModeTest, where Mode can be Experimental, " + "a dashboard test. All tests are , where Mode can be Experimental, " "Nightly, and Continuous, and Test can be Start, Update, Configure, " "Build, Test, Coverage, and Submit."}, - {"-M ", "Sets the model for a dashboard", + {"-M , --test-model ", "Sets the model for a dashboard", "This option tells ctest to act as a Dart client " "where the TestModel can be Experimental, " "Nightly, and Continuous. Combining -M and -T is similar to -D"}, - {"-T ", "Sets the dashboard action to perform", + {"-T , --test-action ", "Sets the dashboard action to perform", "This option tells ctest to act as a Dart client " "and perform some action such as start, build, test etc. " "Combining -M and -T is similar to -D"}, - {"-S ", "Execute a dashboard for a configuration", + {"-S