diff options
author | Brad King <brad.king@kitware.com> | 2019-03-21 13:44:02 (GMT) |
---|---|---|
committer | Kitware Robot <kwrobot@kitware.com> | 2019-03-21 13:44:13 (GMT) |
commit | 732b7b9dd0aedcfe6281613bc16eee4540ecd387 (patch) | |
tree | df846e6b3c98eb30205fd899bb68a05cb18ae138 /Source | |
parent | b581cd01744b5d897ef964176d32ef1c1b7e421f (diff) | |
parent | 5a72dbd40cee412d63099ec7c84f0e1276dc97bf (diff) | |
download | CMake-732b7b9dd0aedcfe6281613bc16eee4540ecd387.zip CMake-732b7b9dd0aedcfe6281613bc16eee4540ecd387.tar.gz CMake-732b7b9dd0aedcfe6281613bc16eee4540ecd387.tar.bz2 |
Merge topic 'ctest-devirtualize-handlers'
5a72dbd40c cmCTest: Remove dead code
a5eeb0310d cmCTest: Cleanup typedefs
71a3391b5f cmCTest: Use default member initialization
b172a81d55 cmCTest: Use concrete accessor functions for TestingHandlers
46090c2337 cmCTest: Store TestingHandlers by value
da5ee509b2 cmCTest: Move all data members to private implementation struct
670d27da64 cmCTest: Remove friend declarations
9406844616 cmCTest: De-inline all member functions
Acked-by: Kitware Robot <kwrobot@kitware.com>
Acked-by: Daniel Pfeifer <daniel@pfeifer-mail.de>
Merge-request: !3114
Diffstat (limited to 'Source')
-rw-r--r-- | Source/CTest/cmCTestBuildCommand.cxx | 11 | ||||
-rw-r--r-- | Source/CTest/cmCTestConfigureCommand.cxx | 11 | ||||
-rw-r--r-- | Source/CTest/cmCTestCoverageCommand.cxx | 8 | ||||
-rw-r--r-- | Source/CTest/cmCTestMemCheckCommand.cxx | 5 | ||||
-rw-r--r-- | Source/CTest/cmCTestRunTest.cxx | 9 | ||||
-rw-r--r-- | Source/CTest/cmCTestSubmitCommand.cxx | 45 | ||||
-rw-r--r-- | Source/CTest/cmCTestSubmitCommand.h | 2 | ||||
-rw-r--r-- | Source/CTest/cmCTestSubmitHandler.cxx | 8 | ||||
-rw-r--r-- | Source/CTest/cmCTestSubmitHandler.h | 4 | ||||
-rw-r--r-- | Source/CTest/cmCTestTestCommand.cxx | 5 | ||||
-rw-r--r-- | Source/CTest/cmCTestUpdateCommand.cxx | 10 | ||||
-rw-r--r-- | Source/CTest/cmCTestUploadCommand.cxx | 12 | ||||
-rw-r--r-- | Source/CTest/cmCTestUploadCommand.h | 6 | ||||
-rw-r--r-- | Source/CTest/cmCTestUploadHandler.cxx | 3 | ||||
-rw-r--r-- | Source/CTest/cmCTestUploadHandler.h | 9 | ||||
-rw-r--r-- | Source/cmCTest.cxx | 1121 | ||||
-rw-r--r-- | Source/cmCTest.h | 258 | ||||
-rw-r--r-- | Source/ctest.cxx | 3 |
18 files changed, 749 insertions, 781 deletions
diff --git a/Source/CTest/cmCTestBuildCommand.cxx b/Source/CTest/cmCTestBuildCommand.cxx index 32f7496..2eacaf1 100644 --- a/Source/CTest/cmCTestBuildCommand.cxx +++ b/Source/CTest/cmCTestBuildCommand.cxx @@ -4,7 +4,6 @@ #include "cmCTest.h" #include "cmCTestBuildHandler.h" -#include "cmCTestGenericHandler.h" #include "cmGlobalGenerator.h" #include "cmMakefile.h" #include "cmMessageType.h" @@ -39,12 +38,10 @@ cmCTestBuildCommand::~cmCTestBuildCommand() cmCTestGenericHandler* cmCTestBuildCommand::InitializeHandler() { - cmCTestGenericHandler* handler = this->CTest->GetInitializedHandler("build"); - if (!handler) { - this->SetError("internal CTest error. Cannot instantiate build handler"); - return nullptr; - } - this->Handler = static_cast<cmCTestBuildHandler*>(handler); + cmCTestBuildHandler* handler = this->CTest->GetBuildHandler(); + handler->Initialize(); + + this->Handler = handler; const char* ctestBuildCommand = this->Makefile->GetDefinition("CTEST_BUILD_COMMAND"); diff --git a/Source/CTest/cmCTestConfigureCommand.cxx b/Source/CTest/cmCTestConfigureCommand.cxx index 7b5c3bc..74a932a 100644 --- a/Source/CTest/cmCTestConfigureCommand.cxx +++ b/Source/CTest/cmCTestConfigureCommand.cxx @@ -3,7 +3,7 @@ #include "cmCTestConfigureCommand.h" #include "cmCTest.h" -#include "cmCTestGenericHandler.h" +#include "cmCTestConfigureHandler.h" #include "cmGlobalGenerator.h" #include "cmMakefile.h" #include "cmSystemTools.h" @@ -142,13 +142,8 @@ cmCTestGenericHandler* cmCTestConfigureCommand::InitializeHandler() labelsForSubprojects, this->Quiet); } - cmCTestGenericHandler* handler = - this->CTest->GetInitializedHandler("configure"); - if (!handler) { - this->SetError( - "internal CTest error. Cannot instantiate configure handler"); - return nullptr; - } + cmCTestConfigureHandler* handler = this->CTest->GetConfigureHandler(); + handler->Initialize(); handler->SetQuiet(this->Quiet); return handler; } diff --git a/Source/CTest/cmCTestCoverageCommand.cxx b/Source/CTest/cmCTestCoverageCommand.cxx index d2003ba..07aae76 100644 --- a/Source/CTest/cmCTestCoverageCommand.cxx +++ b/Source/CTest/cmCTestCoverageCommand.cxx @@ -19,12 +19,8 @@ cmCTestGenericHandler* cmCTestCoverageCommand::InitializeHandler() this->CTest->SetCTestConfigurationFromCMakeVariable( this->Makefile, "CoverageExtraFlags", "CTEST_COVERAGE_EXTRA_FLAGS", this->Quiet); - cmCTestCoverageHandler* handler = static_cast<cmCTestCoverageHandler*>( - this->CTest->GetInitializedHandler("coverage")); - if (!handler) { - this->SetError("internal CTest error. Cannot instantiate test handler"); - return nullptr; - } + cmCTestCoverageHandler* handler = this->CTest->GetCoverageHandler(); + handler->Initialize(); // If a LABELS option was given, select only files with the labels. if (this->LabelsMentioned) { diff --git a/Source/CTest/cmCTestMemCheckCommand.cxx b/Source/CTest/cmCTestMemCheckCommand.cxx index a5d5995..7dad1ce 100644 --- a/Source/CTest/cmCTestMemCheckCommand.cxx +++ b/Source/CTest/cmCTestMemCheckCommand.cxx @@ -7,7 +7,6 @@ #include <vector> #include "cmCTest.h" -#include "cmCTestGenericHandler.h" #include "cmCTestMemCheckHandler.h" #include "cmMakefile.h" @@ -20,8 +19,8 @@ cmCTestMemCheckCommand::cmCTestMemCheckCommand() cmCTestGenericHandler* cmCTestMemCheckCommand::InitializeActualHandler() { - cmCTestGenericHandler* handler = - this->CTest->GetInitializedHandler("memcheck"); + cmCTestMemCheckHandler* handler = this->CTest->GetMemCheckHandler(); + handler->Initialize(); this->CTest->SetCTestConfigurationFromCMakeVariable( this->Makefile, "MemoryCheckType", "CTEST_MEMORYCHECK_TYPE", this->Quiet); diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx index 3bf2087..31976b9 100644 --- a/Source/CTest/cmCTestRunTest.cxx +++ b/Source/CTest/cmCTestRunTest.cxx @@ -132,14 +132,17 @@ bool cmCTestRunTest::EndTest(size_t completed, size_t total, bool started) } else { this->TestResult.Status = cmCTestTestHandler::FAILED; outputStream << "***Failed " << reason; - outputTestErrorsToConsole = this->CTest->OutputTestOutputOnTestFailure; + outputTestErrorsToConsole = + this->CTest->GetOutputTestOutputOnTestFailure(); } } else if (res == cmProcess::State::Expired) { outputStream << "***Timeout "; this->TestResult.Status = cmCTestTestHandler::TIMEOUT; - outputTestErrorsToConsole = this->CTest->OutputTestOutputOnTestFailure; + outputTestErrorsToConsole = + this->CTest->GetOutputTestOutputOnTestFailure(); } else if (res == cmProcess::State::Exception) { - outputTestErrorsToConsole = this->CTest->OutputTestOutputOnTestFailure; + outputTestErrorsToConsole = + this->CTest->GetOutputTestOutputOnTestFailure(); outputStream << "***Exception: "; this->TestResult.ExceptionStatus = this->TestProcess->GetExitExceptionString(); diff --git a/Source/CTest/cmCTestSubmitCommand.cxx b/Source/CTest/cmCTestSubmitCommand.cxx index 00c0610..e31d982 100644 --- a/Source/CTest/cmCTestSubmitCommand.cxx +++ b/Source/CTest/cmCTestSubmitCommand.cxx @@ -3,7 +3,6 @@ #include "cmCTestSubmitCommand.h" #include "cmCTest.h" -#include "cmCTestGenericHandler.h" #include "cmCTestSubmitHandler.h" #include "cmMakefile.h" #include "cmMessageType.h" @@ -42,33 +41,23 @@ cmCTestGenericHandler* cmCTestSubmitCommand::InitializeHandler() this->Makefile->GetDefinition("CTEST_NOTES_FILES"); if (notesFilesVariable) { std::vector<std::string> notesFiles; - cmCTest::VectorOfStrings newNotesFiles; cmSystemTools::ExpandListArgument(notesFilesVariable, notesFiles); - newNotesFiles.insert(newNotesFiles.end(), notesFiles.begin(), - notesFiles.end()); - this->CTest->GenerateNotesFile(newNotesFiles); + this->CTest->GenerateNotesFile(notesFiles); } const char* extraFilesVariable = this->Makefile->GetDefinition("CTEST_EXTRA_SUBMIT_FILES"); if (extraFilesVariable) { std::vector<std::string> extraFiles; - cmCTest::VectorOfStrings newExtraFiles; cmSystemTools::ExpandListArgument(extraFilesVariable, extraFiles); - newExtraFiles.insert(newExtraFiles.end(), extraFiles.begin(), - extraFiles.end()); - if (!this->CTest->SubmitExtraFiles(newExtraFiles)) { + if (!this->CTest->SubmitExtraFiles(extraFiles)) { this->SetError("problem submitting extra files."); return nullptr; } } - cmCTestGenericHandler* handler = - this->CTest->GetInitializedHandler("submit"); - if (!handler) { - this->SetError("internal CTest error. Cannot instantiate submit handler"); - return nullptr; - } + cmCTestSubmitHandler* handler = this->CTest->GetSubmitHandler(); + handler->Initialize(); // If no FILES or PARTS given, *all* PARTS are submitted by default. // @@ -90,38 +79,30 @@ cmCTestGenericHandler* cmCTestSubmitCommand::InitializeHandler() // But FILES with no PARTS mentioned should just submit the FILES // without any of the default parts. // - std::set<cmCTest::Part> noParts; - static_cast<cmCTestSubmitHandler*>(handler)->SelectParts(noParts); - - static_cast<cmCTestSubmitHandler*>(handler)->SelectFiles(this->Files); + handler->SelectParts(std::set<cmCTest::Part>()); + handler->SelectFiles(this->Files); } // If a PARTS option was given, select only the named parts for submission. // if (this->PartsMentioned) { - static_cast<cmCTestSubmitHandler*>(handler)->SelectParts(this->Parts); + handler->SelectParts(this->Parts); } // Pass along any HTTPHEADER to the handler if this option was given. if (!this->HttpHeaders.empty()) { - static_cast<cmCTestSubmitHandler*>(handler)->SetHttpHeaders( - this->HttpHeaders); + handler->SetHttpHeaders(this->HttpHeaders); } - static_cast<cmCTestSubmitHandler*>(handler)->SetOption( - "RetryDelay", this->RetryDelay.c_str()); - static_cast<cmCTestSubmitHandler*>(handler)->SetOption( - "RetryCount", this->RetryCount.c_str()); - static_cast<cmCTestSubmitHandler*>(handler)->SetOption( - "InternalTest", this->InternalTest ? "ON" : "OFF"); + handler->SetOption("RetryDelay", this->RetryDelay.c_str()); + handler->SetOption("RetryCount", this->RetryCount.c_str()); + handler->SetOption("InternalTest", this->InternalTest ? "ON" : "OFF"); handler->SetQuiet(this->Quiet); if (this->CDashUpload) { - static_cast<cmCTestSubmitHandler*>(handler)->SetOption( - "CDashUploadFile", this->CDashUploadFile.c_str()); - static_cast<cmCTestSubmitHandler*>(handler)->SetOption( - "CDashUploadType", this->CDashUploadType.c_str()); + handler->SetOption("CDashUploadFile", this->CDashUploadFile.c_str()); + handler->SetOption("CDashUploadType", this->CDashUploadType.c_str()); } return handler; } diff --git a/Source/CTest/cmCTestSubmitCommand.h b/Source/CTest/cmCTestSubmitCommand.h index 0caccd6..4b1bb26 100644 --- a/Source/CTest/cmCTestSubmitCommand.h +++ b/Source/CTest/cmCTestSubmitCommand.h @@ -79,7 +79,7 @@ protected: std::set<cmCTest::Part> Parts; bool FilesMentioned; bool InternalTest; - cmCTest::SetOfStrings Files; + std::set<std::string> Files; std::string RetryCount; std::string RetryDelay; bool CDashUpload; diff --git a/Source/CTest/cmCTestSubmitHandler.cxx b/Source/CTest/cmCTestSubmitHandler.cxx index 1539635..2b54365 100644 --- a/Source/CTest/cmCTestSubmitHandler.cxx +++ b/Source/CTest/cmCTestSubmitHandler.cxx @@ -259,8 +259,7 @@ bool cmCTestSubmitHandler::SubmitUsingHTTP( upload_as += ctest_curl.Escape(this->CTest->GetCurrentTag()); upload_as += "-"; upload_as += ctest_curl.Escape(this->CTest->GetTestModelString()); - cmCTestScriptHandler* ch = static_cast<cmCTestScriptHandler*>( - this->CTest->GetHandler("script")); + cmCTestScriptHandler* ch = this->CTest->GetScriptHandler(); cmake* cm = ch->GetCMake(); if (cm) { const char* subproject = @@ -558,8 +557,7 @@ int cmCTestSubmitHandler::HandleCDashUploadFile(std::string const& file, // has already been uploaded // TODO I added support for subproject. You would need to add // a "&subproject=subprojectname" to the first POST. - cmCTestScriptHandler* ch = - static_cast<cmCTestScriptHandler*>(this->CTest->GetHandler("script")); + cmCTestScriptHandler* ch = this->CTest->GetScriptHandler(); cmake* cm = ch->GetCMake(); const char* subproject = cm->GetState()->GetGlobalProperty("SubProject"); // TODO: Encode values for a URL instead of trusting caller. @@ -902,7 +900,7 @@ void cmCTestSubmitHandler::SelectParts(std::set<cmCTest::Part> const& parts) } } -void cmCTestSubmitHandler::SelectFiles(cmCTest::SetOfStrings const& files) +void cmCTestSubmitHandler::SelectFiles(std::set<std::string> const& files) { this->Files.insert(files.begin(), files.end()); } diff --git a/Source/CTest/cmCTestSubmitHandler.h b/Source/CTest/cmCTestSubmitHandler.h index 58f4f97..e0fed10 100644 --- a/Source/CTest/cmCTestSubmitHandler.h +++ b/Source/CTest/cmCTestSubmitHandler.h @@ -38,7 +38,7 @@ public: void SelectParts(std::set<cmCTest::Part> const& parts); /** Specify a set of files to submit. */ - void SelectFiles(cmCTest::SetOfStrings const& files); + void SelectFiles(std::set<std::string> const& files); // handle the cdash file upload protocol int HandleCDashUploadFile(std::string const& file, std::string const& type); @@ -74,7 +74,7 @@ private: bool SubmitPart[cmCTest::PartCount]; bool HasWarnings; bool HasErrors; - cmCTest::SetOfStrings Files; + std::set<std::string> Files; std::vector<std::string> HttpHeaders; }; diff --git a/Source/CTest/cmCTestTestCommand.cxx b/Source/CTest/cmCTestTestCommand.cxx index 895ca12..cfd5e3d 100644 --- a/Source/CTest/cmCTestTestCommand.cxx +++ b/Source/CTest/cmCTestTestCommand.cxx @@ -4,6 +4,7 @@ #include "cmCTest.h" #include "cmCTestGenericHandler.h" +#include "cmCTestTestHandler.h" #include "cmDuration.h" #include "cmMakefile.h" #include "cmSystemTools.h" @@ -140,5 +141,7 @@ cmCTestGenericHandler* cmCTestTestCommand::InitializeHandler() cmCTestGenericHandler* cmCTestTestCommand::InitializeActualHandler() { - return this->CTest->GetInitializedHandler("test"); + cmCTestTestHandler* handler = this->CTest->GetTestHandler(); + handler->Initialize(); + return handler; } diff --git a/Source/CTest/cmCTestUpdateCommand.cxx b/Source/CTest/cmCTestUpdateCommand.cxx index 3d800f8..a2f1462 100644 --- a/Source/CTest/cmCTestUpdateCommand.cxx +++ b/Source/CTest/cmCTestUpdateCommand.cxx @@ -3,7 +3,7 @@ #include "cmCTestUpdateCommand.h" #include "cmCTest.h" -#include "cmCTestGenericHandler.h" +#include "cmCTestUpdateHandler.h" #include "cmMakefile.h" #include "cmSystemTools.h" @@ -74,12 +74,8 @@ cmCTestGenericHandler* cmCTestUpdateCommand::InitializeHandler() this->CTest->SetCTestConfigurationFromCMakeVariable( this->Makefile, "P4Options", "CTEST_P4_OPTIONS", this->Quiet); - cmCTestGenericHandler* handler = - this->CTest->GetInitializedHandler("update"); - if (!handler) { - this->SetError("internal CTest error. Cannot instantiate update handler"); - return nullptr; - } + cmCTestUpdateHandler* handler = this->CTest->GetUpdateHandler(); + handler->Initialize(); handler->SetCommand(this); if (source_dir.empty()) { this->SetError("source directory not specified. Please use SOURCE tag"); diff --git a/Source/CTest/cmCTestUploadCommand.cxx b/Source/CTest/cmCTestUploadCommand.cxx index 2fe2cd3..59fbf37 100644 --- a/Source/CTest/cmCTestUploadCommand.cxx +++ b/Source/CTest/cmCTestUploadCommand.cxx @@ -6,7 +6,6 @@ #include <vector> #include "cmCTest.h" -#include "cmCTestGenericHandler.h" #include "cmCTestUploadHandler.h" #include "cmMakefile.h" #include "cmMessageType.h" @@ -14,14 +13,9 @@ cmCTestGenericHandler* cmCTestUploadCommand::InitializeHandler() { - cmCTestGenericHandler* handler = - this->CTest->GetInitializedHandler("upload"); - if (!handler) { - this->SetError("internal CTest error. Cannot instantiate upload handler"); - return nullptr; - } - static_cast<cmCTestUploadHandler*>(handler)->SetFiles(this->Files); - + cmCTestUploadHandler* handler = this->CTest->GetUploadHandler(); + handler->Initialize(); + handler->SetFiles(this->Files); handler->SetQuiet(this->Quiet); return handler; } diff --git a/Source/CTest/cmCTestUploadCommand.h b/Source/CTest/cmCTestUploadCommand.h index 61bf1cc..0d3b06e 100644 --- a/Source/CTest/cmCTestUploadCommand.h +++ b/Source/CTest/cmCTestUploadCommand.h @@ -5,9 +5,9 @@ #include "cmConfigure.h" // IWYU pragma: keep -#include "cmCTest.h" #include "cmCTestHandlerCommand.h" +#include <set> #include <string> class cmCTestGenericHandler; @@ -22,8 +22,6 @@ class cmCommand; class cmCTestUploadCommand : public cmCTestHandlerCommand { public: - cmCTestUploadCommand() {} - /** * This is a virtual constructor for the command. */ @@ -55,7 +53,7 @@ protected: ArgumentDoingLast2 }; - cmCTest::SetOfStrings Files; + std::set<std::string> Files; }; #endif diff --git a/Source/CTest/cmCTestUploadHandler.cxx b/Source/CTest/cmCTestUploadHandler.cxx index 261ecab..ee9ee91 100644 --- a/Source/CTest/cmCTestUploadHandler.cxx +++ b/Source/CTest/cmCTestUploadHandler.cxx @@ -2,6 +2,7 @@ file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmCTestUploadHandler.h" +#include "cmCTest.h" #include "cmGeneratedFileStream.h" #include "cmVersion.h" #include "cmXMLWriter.h" @@ -20,7 +21,7 @@ void cmCTestUploadHandler::Initialize() this->Files.clear(); } -void cmCTestUploadHandler::SetFiles(const cmCTest::SetOfStrings& files) +void cmCTestUploadHandler::SetFiles(std::set<std::string> const& files) { this->Files = files; } diff --git a/Source/CTest/cmCTestUploadHandler.h b/Source/CTest/cmCTestUploadHandler.h index ff50574..4d8fab4 100644 --- a/Source/CTest/cmCTestUploadHandler.h +++ b/Source/CTest/cmCTestUploadHandler.h @@ -5,9 +5,11 @@ #include "cmConfigure.h" // IWYU pragma: keep -#include "cmCTest.h" #include "cmCTestGenericHandler.h" +#include <set> +#include <string> + /** \class cmCTestUploadHandler * \brief Helper class for CTest * @@ -20,7 +22,6 @@ public: typedef cmCTestGenericHandler Superclass; cmCTestUploadHandler(); - ~cmCTestUploadHandler() override {} /* * The main entry point for this class @@ -30,10 +31,10 @@ public: void Initialize() override; /** Specify a set of files to submit. */ - void SetFiles(cmCTest::SetOfStrings const& files); + void SetFiles(std::set<std::string> const& files); private: - cmCTest::SetOfStrings Files; + std::set<std::string> Files; }; #endif diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx index c77bb97..709feac 100644 --- a/Source/cmCTest.cxx +++ b/Source/cmCTest.cxx @@ -43,7 +43,6 @@ #include "cmCTestTestHandler.h" #include "cmCTestUpdateHandler.h" #include "cmCTestUploadHandler.h" -#include "cmCurl.h" #include "cmDynamicLoader.h" #include "cmGeneratedFileStream.h" #include "cmGlobalGenerator.h" @@ -62,12 +61,149 @@ # include <be/kernel/OS.h> /* disable_debugger() API. */ #endif -#define DEBUGOUT \ - std::cout << __LINE__ << " "; \ - std::cout -#define DEBUGERR \ - std::cerr << __LINE__ << " "; \ - std::cerr +struct cmCTest::Private +{ + /** Representation of one part. */ + struct PartInfo + { + void SetName(const std::string& name) { this->Name = name; } + const std::string& GetName() const { return this->Name; } + + void Enable() { this->Enabled = true; } + explicit operator bool() const { return this->Enabled; } + + std::vector<std::string> SubmitFiles; + + private: + bool Enabled = false; + std::string Name; + }; + + int RepeatTests = 1; // default to run each test once + bool RepeatUntilFail = false; + std::string ConfigType; + std::string ScheduleType; + std::chrono::system_clock::time_point StopTime; + bool TestProgressOutput = false; + bool Verbose = false; + bool ExtraVerbose = false; + bool ProduceXML = false; + bool LabelSummary = true; + bool SubprojectSummary = true; + bool UseHTTP10 = false; + bool PrintLabels = false; + bool Failover = false; + + bool FlushTestProgressLine = false; + + bool ForceNewCTestProcess = false; + + bool RunConfigurationScript = false; + + // these are helper classes + cmCTestBuildHandler BuildHandler; + cmCTestBuildAndTestHandler BuildAndTestHandler; + cmCTestCoverageHandler CoverageHandler; + cmCTestScriptHandler ScriptHandler; + cmCTestTestHandler TestHandler; + cmCTestUpdateHandler UpdateHandler; + cmCTestConfigureHandler ConfigureHandler; + cmCTestMemCheckHandler MemCheckHandler; + cmCTestSubmitHandler SubmitHandler; + cmCTestUploadHandler UploadHandler; + + std::vector<cmCTestGenericHandler*> GetTestingHandlers() + { + return { &this->BuildHandler, &this->BuildAndTestHandler, + &this->CoverageHandler, &this->ScriptHandler, + &this->TestHandler, &this->UpdateHandler, + &this->ConfigureHandler, &this->MemCheckHandler, + &this->SubmitHandler, &this->UploadHandler }; + } + + std::map<std::string, cmCTestGenericHandler*> GetNamedTestingHandlers() + { + return { { "build", &this->BuildHandler }, + { "buildtest", &this->BuildAndTestHandler }, + { "coverage", &this->CoverageHandler }, + { "script", &this->ScriptHandler }, + { "test", &this->TestHandler }, + { "update", &this->UpdateHandler }, + { "configure", &this->ConfigureHandler }, + { "memcheck", &this->MemCheckHandler }, + { "submit", &this->SubmitHandler }, + { "upload", &this->UploadHandler } }; + } + + bool ShowOnly = false; + bool OutputAsJson = false; + int OutputAsJsonVersion = 1; + + // TODO: The ctest configuration should be a hierarchy of + // configuration option sources: command-line, script, ini file. + // Then the ini file can get re-loaded whenever it changes without + // affecting any higher-precedence settings. + std::map<std::string, std::string> CTestConfiguration; + std::map<std::string, std::string> CTestConfigurationOverwrites; + + PartInfo Parts[PartCount]; + std::map<std::string, Part> PartMap; + + std::string CurrentTag; + bool TomorrowTag = false; + + int TestModel = cmCTest::EXPERIMENTAL; + std::string SpecificTrack; + + cmDuration TimeOut = cmDuration::zero(); + + cmDuration GlobalTimeout = cmDuration::zero(); + + int MaxTestNameWidth = 30; + + int ParallelLevel = 1; + bool ParallelLevelSetInCli = false; + + unsigned long TestLoad = 0; + + int CompatibilityMode; + + // information for the --build-and-test options + std::string BinaryDir; + + std::string NotesFiles; + + bool InteractiveDebugMode = true; + + bool ShortDateFormat = true; + + bool CompressXMLFiles = false; + bool CompressTestOutput = true; + + // By default we write output to the process output streams. + std::ostream* StreamOut = &std::cout; + std::ostream* StreamErr = &std::cerr; + + bool SuppressUpdatingCTestConfiguration = false; + + bool Debug = false; + bool ShowLineNumbers = false; + bool Quiet = false; + + std::string BuildID; + + std::vector<std::string> InitialCommandLineArguments; + + int SubmitIndex = 0; + + cmGeneratedFileStream* OutputLogFile = nullptr; + int OutputLogFileLastTag = -1; + + bool OutputTestOutputOnTestFailure = false; + bool OutputColorCode = cmCTest::ColoredOutputSupportedByConsole(); + + std::map<std::string, std::string> Definitions; +}; struct tm* cmCTest::GetNightlyTime(std::string const& str, bool tomorrowtag) { @@ -123,6 +259,11 @@ struct tm* cmCTest::GetNightlyTime(std::string const& str, bool tomorrowtag) return lctime; } +bool cmCTest::GetTomorrowTag() const +{ + return this->Impl->TomorrowTag; +} + std::string cmCTest::CleanString(const std::string& str) { std::string::size_type spos = str.find_first_not_of(" \n\t\r\f\v"); @@ -142,7 +283,7 @@ std::string cmCTest::CurrentTime() struct tm* t = localtime(¤ttime); // return ::CleanString(ctime(¤ttime)); char current_time[1024]; - if (this->ShortDateFormat) { + if (this->Impl->ShortDateFormat) { strftime(current_time, 1000, "%b %d %H:%M %Z", t); } else { strftime(current_time, 1000, "%a %b %d %H:%M:%S %Z %Y", t); @@ -160,88 +301,6 @@ std::string cmCTest::GetCostDataFile() return fname; } -#ifdef CMAKE_BUILD_WITH_CMAKE -static size_t HTTPResponseCallback(void* ptr, size_t size, size_t nmemb, - void* data) -{ - int realsize = static_cast<int>(size * nmemb); - - std::string* response = static_cast<std::string*>(data); - const char* chPtr = static_cast<char*>(ptr); - *response += chPtr; - - return realsize; -} - -int cmCTest::HTTPRequest(std::string url, HTTPMethod method, - std::string& response, std::string const& fields, - std::string const& putFile, int timeout) -{ - CURL* curl; - FILE* file; - ::curl_global_init(CURL_GLOBAL_ALL); - curl = ::curl_easy_init(); - cmCurlSetCAInfo(curl); - - // set request options based on method - switch (method) { - case cmCTest::HTTP_POST: - ::curl_easy_setopt(curl, CURLOPT_POST, 1); - ::curl_easy_setopt(curl, CURLOPT_POSTFIELDS, fields.c_str()); - break; - case cmCTest::HTTP_PUT: - if (!cmSystemTools::FileExists(putFile)) { - response = "Error: File "; - response += putFile + " does not exist.\n"; - return -1; - } - ::curl_easy_setopt(curl, CURLOPT_PUT, 1); - file = cmsys::SystemTools::Fopen(putFile, "rb"); - ::curl_easy_setopt(curl, CURLOPT_INFILE, file); - // fall through to append GET fields - CM_FALLTHROUGH; - case cmCTest::HTTP_GET: - if (!fields.empty()) { - url += "?" + fields; - } - break; - } - - ::curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); - ::curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout); - ::curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); - - // set response options - ::curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, HTTPResponseCallback); - ::curl_easy_setopt(curl, CURLOPT_FILE, &response); - ::curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1); - - CURLcode res = ::curl_easy_perform(curl); - - ::curl_easy_cleanup(curl); - ::curl_global_cleanup(); - - return static_cast<int>(res); -} -#endif - -std::string cmCTest::MakeURLSafe(const std::string& str) -{ - std::ostringstream ost; - char buffer[10]; - for (unsigned char ch : str) { - if ((ch > 126 || ch < 32 || ch == '&' || ch == '%' || ch == '+' || - ch == '=' || ch == '@') && - ch != 9) { - sprintf(buffer, "%02x;", static_cast<unsigned int>(ch)); - ost << buffer; - } else { - ost << ch; - } - } - return ost.str(); -} - std::string cmCTest::DecodeURL(const std::string& in) { std::string out; @@ -258,92 +317,39 @@ std::string cmCTest::DecodeURL(const std::string& in) } cmCTest::cmCTest() + : Impl(new Private) { - this->LabelSummary = true; - this->SubprojectSummary = true; - this->ParallelLevel = 1; - this->ParallelLevelSetInCli = false; - this->TestLoad = 0; - this->SubmitIndex = 0; - this->Failover = false; - this->ForceNewCTestProcess = false; - this->TomorrowTag = false; - this->TestProgressOutput = false; - this->FlushTestProgressLine = false; - this->Verbose = false; - - this->Debug = false; - this->ShowLineNumbers = false; - this->Quiet = false; - this->ExtraVerbose = false; - this->ProduceXML = false; - this->ShowOnly = false; - this->OutputAsJson = false; - this->OutputAsJsonVersion = 1; - this->RunConfigurationScript = false; - this->UseHTTP10 = false; - this->PrintLabels = false; - this->CompressTestOutput = true; - this->TestModel = cmCTest::EXPERIMENTAL; - this->MaxTestNameWidth = 30; - this->InteractiveDebugMode = true; - this->TimeOut = cmDuration::zero(); - this->GlobalTimeout = cmDuration::zero(); - this->CompressXMLFiles = false; - this->ScheduleType.clear(); - this->OutputLogFile = nullptr; - this->OutputLogFileLastTag = -1; - this->SuppressUpdatingCTestConfiguration = false; - this->BuildID = ""; - this->OutputTestOutputOnTestFailure = false; - this->OutputColorCode = cmCTest::ColoredOutputSupportedByConsole(); - this->RepeatTests = 1; // default to run each test once - this->RepeatUntilFail = false; - std::string envValue; if (cmSystemTools::GetEnv("CTEST_OUTPUT_ON_FAILURE", envValue)) { - this->OutputTestOutputOnTestFailure = !cmSystemTools::IsOff(envValue); + this->Impl->OutputTestOutputOnTestFailure = + !cmSystemTools::IsOff(envValue); } envValue.clear(); if (cmSystemTools::GetEnv("CTEST_PROGRESS_OUTPUT", envValue)) { - this->TestProgressOutput = !cmSystemTools::IsOff(envValue); - } - - this->InitStreams(); - - this->Parts[PartStart].SetName("Start"); - this->Parts[PartUpdate].SetName("Update"); - this->Parts[PartConfigure].SetName("Configure"); - this->Parts[PartBuild].SetName("Build"); - this->Parts[PartTest].SetName("Test"); - this->Parts[PartCoverage].SetName("Coverage"); - this->Parts[PartMemCheck].SetName("MemCheck"); - this->Parts[PartSubmit].SetName("Submit"); - this->Parts[PartNotes].SetName("Notes"); - this->Parts[PartExtraFiles].SetName("ExtraFiles"); - this->Parts[PartUpload].SetName("Upload"); - this->Parts[PartDone].SetName("Done"); + this->Impl->TestProgressOutput = !cmSystemTools::IsOff(envValue); + } + + this->Impl->Parts[PartStart].SetName("Start"); + this->Impl->Parts[PartUpdate].SetName("Update"); + this->Impl->Parts[PartConfigure].SetName("Configure"); + this->Impl->Parts[PartBuild].SetName("Build"); + this->Impl->Parts[PartTest].SetName("Test"); + this->Impl->Parts[PartCoverage].SetName("Coverage"); + this->Impl->Parts[PartMemCheck].SetName("MemCheck"); + this->Impl->Parts[PartSubmit].SetName("Submit"); + this->Impl->Parts[PartNotes].SetName("Notes"); + this->Impl->Parts[PartExtraFiles].SetName("ExtraFiles"); + this->Impl->Parts[PartUpload].SetName("Upload"); + this->Impl->Parts[PartDone].SetName("Done"); // Fill the part name-to-id map. for (Part p = PartStart; p != PartCount; p = Part(p + 1)) { - this->PartMap[cmSystemTools::LowerCase(this->Parts[p].GetName())] = p; + this->Impl + ->PartMap[cmSystemTools::LowerCase(this->Impl->Parts[p].GetName())] = p; } - this->ShortDateFormat = true; - - this->TestingHandlers["build"] = new cmCTestBuildHandler; - this->TestingHandlers["buildtest"] = new cmCTestBuildAndTestHandler; - this->TestingHandlers["coverage"] = new cmCTestCoverageHandler; - this->TestingHandlers["script"] = new cmCTestScriptHandler; - this->TestingHandlers["test"] = new cmCTestTestHandler; - this->TestingHandlers["update"] = new cmCTestUpdateHandler; - this->TestingHandlers["configure"] = new cmCTestConfigureHandler; - this->TestingHandlers["memcheck"] = new cmCTestMemCheckHandler; - this->TestingHandlers["submit"] = new cmCTestSubmitHandler; - this->TestingHandlers["upload"] = new cmCTestUploadHandler; - - for (auto& handler : this->TestingHandlers) { - handler.second->SetCTestInstance(this); + for (auto& handler : this->Impl->GetTestingHandlers()) { + handler->SetCTestInstance(this); } // Make sure we can capture the build tool output. @@ -352,31 +358,40 @@ cmCTest::cmCTest() cmCTest::~cmCTest() { - cmDeleteAll(this->TestingHandlers); - this->SetOutputLogFileName(nullptr); + delete this->Impl->OutputLogFile; +} + +int cmCTest::GetParallelLevel() const +{ + return this->Impl->ParallelLevel; } void cmCTest::SetParallelLevel(int level) { - this->ParallelLevel = level < 1 ? 1 : level; + this->Impl->ParallelLevel = level < 1 ? 1 : level; +} + +unsigned long cmCTest::GetTestLoad() const +{ + return this->Impl->TestLoad; } void cmCTest::SetTestLoad(unsigned long load) { - this->TestLoad = load; + this->Impl->TestLoad = load; } bool cmCTest::ShouldCompressTestOutput() { - return this->CompressTestOutput; + return this->Impl->CompressTestOutput; } cmCTest::Part cmCTest::GetPartFromName(const char* name) { // Look up by lower-case to make names case-insensitive. std::string lower_name = cmSystemTools::LowerCase(name); - PartMapType::const_iterator i = this->PartMap.find(lower_name); - if (i != this->PartMap.end()) { + auto const i = this->Impl->PartMap.find(lower_name); + if (i != this->Impl->PartMap.end()) { return i->second; } @@ -392,19 +407,19 @@ int cmCTest::Initialize(const char* binary_dir, cmCTestStartCommand* command) } cmCTestOptionalLog(this, DEBUG, "Here: " << __LINE__ << std::endl, quiet); - if (!this->InteractiveDebugMode) { + if (!this->Impl->InteractiveDebugMode) { this->BlockTestErrorDiagnostics(); } else { cmSystemTools::PutEnv("CTEST_INTERACTIVE_DEBUG_MODE=1"); } - this->BinaryDir = binary_dir; - cmSystemTools::ConvertToUnixSlashes(this->BinaryDir); + this->Impl->BinaryDir = binary_dir; + cmSystemTools::ConvertToUnixSlashes(this->Impl->BinaryDir); this->UpdateCTestConfiguration(); cmCTestOptionalLog(this, DEBUG, "Here: " << __LINE__ << std::endl, quiet); - if (this->ProduceXML) { + if (this->Impl->ProduceXML) { cmCTestOptionalLog(this, DEBUG, "Here: " << __LINE__ << std::endl, quiet); cmCTestOptionalLog(this, OUTPUT, " Site: " @@ -415,7 +430,7 @@ int cmCTest::Initialize(const char* binary_dir, cmCTestStartCommand* command) << std::endl, quiet); cmCTestOptionalLog(this, DEBUG, "Produce XML is on" << std::endl, quiet); - if (this->TestModel == cmCTest::NIGHTLY && + if (this->Impl->TestModel == cmCTest::NIGHTLY && this->GetCTestConfiguration("NightlyStartTime").empty()) { cmCTestOptionalLog( this, WARNING, @@ -435,17 +450,18 @@ int cmCTest::Initialize(const char* binary_dir, cmCTestStartCommand* command) cm.GetCurrentSnapshot().SetDefaultDefinitions(); cmGlobalGenerator gg(&cm); cmMakefile mf(&gg, cm.GetCurrentSnapshot()); - if (!this->ReadCustomConfigurationFileTree(this->BinaryDir.c_str(), &mf)) { + if (!this->ReadCustomConfigurationFileTree(this->Impl->BinaryDir.c_str(), + &mf)) { cmCTestOptionalLog( this, DEBUG, "Cannot find custom configuration file tree" << std::endl, quiet); return 0; } - if (this->ProduceXML) { + if (this->Impl->ProduceXML) { // Verify "Testing" directory exists: // - std::string testingDir = this->BinaryDir + "/Testing"; + std::string testingDir = this->Impl->BinaryDir + "/Testing"; if (cmSystemTools::FileExists(testingDir)) { if (!cmSystemTools::FileIsDirectory(testingDir)) { cmCTestLog(this, ERROR_MESSAGE, @@ -475,7 +491,7 @@ int cmCTest::Initialize(const char* binary_dir, cmCTestStartCommand* command) if (createNewTag) { time_t tctime = time(nullptr); - if (this->TomorrowTag) { + if (this->Impl->TomorrowTag) { tctime += (24 * 60 * 60); } struct tm* lctime = gmtime(&tctime); @@ -493,26 +509,28 @@ int cmCTest::Initialize(const char* binary_dir, cmCTestStartCommand* command) } std::string track; if (cmSystemTools::GetLineFromStream(tfin, track) && - !this->Parts[PartStart] && !command) { - this->SpecificTrack = track; + !this->Impl->Parts[PartStart] && !command) { + this->Impl->SpecificTrack = track; } std::string model; if (cmSystemTools::GetLineFromStream(tfin, model) && - !this->Parts[PartStart] && !command) { - this->TestModel = GetTestModelFromString(model.c_str()); + !this->Impl->Parts[PartStart] && !command) { + this->Impl->TestModel = GetTestModelFromString(model.c_str()); } tfin.close(); } - if (tag.empty() || (nullptr != command) || this->Parts[PartStart]) { + if (tag.empty() || (nullptr != command) || + this->Impl->Parts[PartStart]) { cmCTestOptionalLog( this, DEBUG, "TestModel: " << this->GetTestModelString() << std::endl, quiet); - cmCTestOptionalLog( - this, DEBUG, "TestModel: " << this->TestModel << std::endl, quiet); - if (this->TestModel == cmCTest::NIGHTLY) { + cmCTestOptionalLog(this, DEBUG, + "TestModel: " << this->Impl->TestModel << std::endl, + quiet); + if (this->Impl->TestModel == cmCTest::NIGHTLY) { lctime = this->GetNightlyTime( this->GetCTestConfiguration("NightlyStartTime"), - this->TomorrowTag); + this->Impl->TomorrowTag); } char datestring[100]; sprintf(datestring, "%04d%02d%02d-%02d%02d", lctime->tm_year + 1900, @@ -523,7 +541,7 @@ int cmCTest::Initialize(const char* binary_dir, cmCTestStartCommand* command) if (ofs) { ofs << tag << std::endl; ofs << this->GetTestModelString() << std::endl; - switch (this->TestModel) { + switch (this->Impl->TestModel) { case cmCTest::EXPERIMENTAL: ofs << "Experimental" << std::endl; break; @@ -565,7 +583,7 @@ int cmCTest::Initialize(const char* binary_dir, cmCTestStartCommand* command) return 0; } - if (this->TestModel == cmCTest::UNKNOWN) { + if (this->Impl->TestModel == cmCTest::UNKNOWN) { if (model == cmCTest::UNKNOWN) { cmCTestLog(this, ERROR_MESSAGE, "TAG file does not contain model and " @@ -577,8 +595,8 @@ int cmCTest::Initialize(const char* binary_dir, cmCTestStartCommand* command) this->SetTestModel(model); } - if (model != this->TestModel && model != cmCTest::UNKNOWN && - this->TestModel != cmCTest::UNKNOWN) { + if (model != this->Impl->TestModel && model != cmCTest::UNKNOWN && + this->Impl->TestModel != cmCTest::UNKNOWN) { cmCTestOptionalLog(this, WARNING, "Model given in TAG does not match " "model given in ctest_start()" @@ -586,14 +604,15 @@ int cmCTest::Initialize(const char* binary_dir, cmCTestStartCommand* command) quiet); } - if (!this->SpecificTrack.empty() && track != this->SpecificTrack) { + if (!this->Impl->SpecificTrack.empty() && + track != this->Impl->SpecificTrack) { cmCTestOptionalLog(this, WARNING, "Track given in TAG does not match " "track given in ctest_start()" << std::endl, quiet); } else { - this->SpecificTrack = track; + this->Impl->SpecificTrack = track; } cmCTestOptionalLog(this, OUTPUT, @@ -603,7 +622,7 @@ int cmCTest::Initialize(const char* binary_dir, cmCTestStartCommand* command) quiet); } - this->CurrentTag = tag; + this->Impl->CurrentTag = tag; } return 1; @@ -613,9 +632,9 @@ bool cmCTest::InitializeFromCommand(cmCTestStartCommand* command) { std::string src_dir = this->GetCTestConfiguration("SourceDirectory"); std::string bld_dir = this->GetCTestConfiguration("BuildDirectory"); - this->BuildID = ""; + this->Impl->BuildID = ""; for (Part p = PartStart; p != PartCount; p = Part(p + 1)) { - this->Parts[p].SubmitFiles.clear(); + this->Impl->Parts[p].SubmitFiles.clear(); } cmMakefile* mf = command->GetMakefile(); @@ -669,18 +688,18 @@ bool cmCTest::InitializeFromCommand(cmCTestStartCommand* command) bool cmCTest::UpdateCTestConfiguration() { - if (this->SuppressUpdatingCTestConfiguration) { + if (this->Impl->SuppressUpdatingCTestConfiguration) { return true; } - std::string fileName = this->BinaryDir + "/CTestConfiguration.ini"; + std::string fileName = this->Impl->BinaryDir + "/CTestConfiguration.ini"; if (!cmSystemTools::FileExists(fileName)) { - fileName = this->BinaryDir + "/DartConfiguration.tcl"; + fileName = this->Impl->BinaryDir + "/DartConfiguration.tcl"; } cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, "UpdateCTestConfiguration from :" << fileName << "\n"); if (!cmSystemTools::FileExists(fileName)) { // No need to exit if we are not producing XML - if (this->ProduceXML) { + if (this->Impl->ProduceXML) { cmCTestLog(this, ERROR_MESSAGE, "Cannot find file: " << fileName << std::endl); return false; @@ -720,15 +739,15 @@ bool cmCTest::UpdateCTestConfiguration() } std::string key = line.substr(0, cpos); std::string value = cmCTest::CleanString(line.substr(cpos + 1)); - this->CTestConfiguration[key] = value; + this->Impl->CTestConfiguration[key] = value; } fin.close(); } if (!this->GetCTestConfiguration("BuildDirectory").empty()) { - this->BinaryDir = this->GetCTestConfiguration("BuildDirectory"); - cmSystemTools::ChangeDirectory(this->BinaryDir); + this->Impl->BinaryDir = this->GetCTestConfiguration("BuildDirectory"); + cmSystemTools::ChangeDirectory(this->Impl->BinaryDir); } - this->TimeOut = + this->Impl->TimeOut = std::chrono::seconds(atoi(this->GetCTestConfiguration("TimeOut").c_str())); std::string const& testLoad = this->GetCTestConfiguration("TestLoad"); if (!testLoad.empty()) { @@ -740,8 +759,8 @@ bool cmCTest::UpdateCTestConfiguration() "Invalid value for 'Test Load' : " << testLoad << std::endl); } } - if (this->ProduceXML) { - this->CompressXMLFiles = + if (this->Impl->ProduceXML) { + this->Impl->CompressXMLFiles = cmSystemTools::IsOn(this->GetCTestConfiguration("CompressSubmission")); } return true; @@ -760,21 +779,26 @@ void cmCTest::BlockTestErrorDiagnostics() void cmCTest::SetTestModel(int mode) { - this->InteractiveDebugMode = false; - this->TestModel = mode; + this->Impl->InteractiveDebugMode = false; + this->Impl->TestModel = mode; +} + +int cmCTest::GetTestModel() const +{ + return this->Impl->TestModel; } bool cmCTest::SetTest(const char* ttype, bool report) { if (cmSystemTools::LowerCase(ttype) == "all") { for (Part p = PartStart; p != PartCount; p = Part(p + 1)) { - this->Parts[p].Enable(); + this->Impl->Parts[p].Enable(); } return true; } Part p = this->GetPartFromName(ttype); if (p != PartCount) { - this->Parts[p].Enable(); + this->Impl->Parts[p].Enable(); return true; } if (report) { @@ -792,7 +816,7 @@ void cmCTest::Finalize() bool cmCTest::OpenOutputFile(const std::string& path, const std::string& name, cmGeneratedFileStream& stream, bool compress) { - std::string testingDir = this->BinaryDir + "/Testing"; + std::string testingDir = this->Impl->BinaryDir + "/Testing"; if (!path.empty()) { testingDir += "/" + path; } @@ -819,7 +843,7 @@ bool cmCTest::OpenOutputFile(const std::string& path, const std::string& name, return false; } if (compress) { - if (this->CompressXMLFiles) { + if (this->Impl->CompressXMLFiles) { stream.SetCompression(true); } } @@ -844,40 +868,59 @@ bool cmCTest::AddIfExists(Part part, const char* file) bool cmCTest::CTestFileExists(const std::string& filename) { - std::string testingDir = - this->BinaryDir + "/Testing/" + this->CurrentTag + "/" + filename; + std::string testingDir = this->Impl->BinaryDir + "/Testing/" + + this->Impl->CurrentTag + "/" + filename; return cmSystemTools::FileExists(testingDir); } -cmCTestGenericHandler* cmCTest::GetInitializedHandler(const char* handler) +cmCTestBuildHandler* cmCTest::GetBuildHandler() { - cmCTest::t_TestingHandlers::iterator it = - this->TestingHandlers.find(handler); - if (it == this->TestingHandlers.end()) { - return nullptr; - } - it->second->Initialize(); - return it->second; + return &this->Impl->BuildHandler; } -cmCTestGenericHandler* cmCTest::GetHandler(const char* handler) +cmCTestBuildAndTestHandler* cmCTest::GetBuildAndTestHandler() { - cmCTest::t_TestingHandlers::iterator it = - this->TestingHandlers.find(handler); - if (it == this->TestingHandlers.end()) { - return nullptr; - } - return it->second; + return &this->Impl->BuildAndTestHandler; } -int cmCTest::ExecuteHandler(const char* shandler) +cmCTestCoverageHandler* cmCTest::GetCoverageHandler() { - cmCTestGenericHandler* handler = this->GetHandler(shandler); - if (!handler) { - return -1; - } - handler->Initialize(); - return handler->ProcessHandler(); + return &this->Impl->CoverageHandler; +} + +cmCTestScriptHandler* cmCTest::GetScriptHandler() +{ + return &this->Impl->ScriptHandler; +} + +cmCTestTestHandler* cmCTest::GetTestHandler() +{ + return &this->Impl->TestHandler; +} + +cmCTestUpdateHandler* cmCTest::GetUpdateHandler() +{ + return &this->Impl->UpdateHandler; +} + +cmCTestConfigureHandler* cmCTest::GetConfigureHandler() +{ + return &this->Impl->ConfigureHandler; +} + +cmCTestMemCheckHandler* cmCTest::GetMemCheckHandler() +{ + return &this->Impl->MemCheckHandler; +} + +cmCTestSubmitHandler* cmCTest::GetSubmitHandler() +{ + return &this->Impl->SubmitHandler; +} + +cmCTestUploadHandler* cmCTest::GetUploadHandler() +{ + return &this->Impl->UploadHandler; } int cmCTest::ProcessSteps() @@ -887,11 +930,11 @@ int cmCTest::ProcessSteps() int update_count = 0; for (Part p = PartStart; notest && p != PartCount; p = Part(p + 1)) { - notest = !this->Parts[p]; + notest = !this->Impl->Parts[p]; } - if (this->Parts[PartUpdate] && + if (this->Impl->Parts[PartUpdate] && (this->GetRemainingTimeAllowed() > std::chrono::minutes(2))) { - cmCTestGenericHandler* uphandler = this->GetHandler("update"); + cmCTestUpdateHandler* uphandler = this->GetUpdateHandler(); uphandler->SetPersistentOption( "SourceDirectory", this->GetCTestConfiguration("SourceDirectory").c_str()); @@ -900,45 +943,45 @@ int cmCTest::ProcessSteps() res |= cmCTest::UPDATE_ERRORS; } } - if (this->TestModel == cmCTest::CONTINUOUS && !update_count) { + if (this->Impl->TestModel == cmCTest::CONTINUOUS && !update_count) { return 0; } - if (this->Parts[PartConfigure] && + if (this->Impl->Parts[PartConfigure] && (this->GetRemainingTimeAllowed() > std::chrono::minutes(2))) { - if (this->GetHandler("configure")->ProcessHandler() < 0) { + if (this->GetConfigureHandler()->ProcessHandler() < 0) { res |= cmCTest::CONFIGURE_ERRORS; } } - if (this->Parts[PartBuild] && + if (this->Impl->Parts[PartBuild] && (this->GetRemainingTimeAllowed() > std::chrono::minutes(2))) { this->UpdateCTestConfiguration(); - if (this->GetHandler("build")->ProcessHandler() < 0) { + if (this->GetBuildHandler()->ProcessHandler() < 0) { res |= cmCTest::BUILD_ERRORS; } } - if ((this->Parts[PartTest] || notest) && + if ((this->Impl->Parts[PartTest] || notest) && (this->GetRemainingTimeAllowed() > std::chrono::minutes(2))) { this->UpdateCTestConfiguration(); - if (this->GetHandler("test")->ProcessHandler() < 0) { + if (this->GetTestHandler()->ProcessHandler() < 0) { res |= cmCTest::TEST_ERRORS; } } - if (this->Parts[PartCoverage] && + if (this->Impl->Parts[PartCoverage] && (this->GetRemainingTimeAllowed() > std::chrono::minutes(2))) { this->UpdateCTestConfiguration(); - if (this->GetHandler("coverage")->ProcessHandler() < 0) { + if (this->GetCoverageHandler()->ProcessHandler() < 0) { res |= cmCTest::COVERAGE_ERRORS; } } - if (this->Parts[PartMemCheck] && + if (this->Impl->Parts[PartMemCheck] && (this->GetRemainingTimeAllowed() > std::chrono::minutes(2))) { this->UpdateCTestConfiguration(); - if (this->GetHandler("memcheck")->ProcessHandler() < 0) { + if (this->GetMemCheckHandler()->ProcessHandler() < 0) { res |= cmCTest::MEMORY_ERRORS; } } if (!notest) { - std::string notes_dir = this->BinaryDir + "/Testing/Notes"; + std::string notes_dir = this->Impl->BinaryDir + "/Testing/Notes"; if (cmSystemTools::FileIsDirectory(notes_dir)) { cmsys::Directory d; d.Load(notes_dir); @@ -948,24 +991,24 @@ int cmCTest::ProcessSteps() std::string fullname = notes_dir + "/" + file; if (cmSystemTools::FileExists(fullname) && !cmSystemTools::FileIsDirectory(fullname)) { - if (!this->NotesFiles.empty()) { - this->NotesFiles += ";"; + if (!this->Impl->NotesFiles.empty()) { + this->Impl->NotesFiles += ";"; } - this->NotesFiles += fullname; - this->Parts[PartNotes].Enable(); + this->Impl->NotesFiles += fullname; + this->Impl->Parts[PartNotes].Enable(); } } } } - if (this->Parts[PartNotes]) { + if (this->Impl->Parts[PartNotes]) { this->UpdateCTestConfiguration(); - if (!this->NotesFiles.empty()) { - this->GenerateNotesFile(this->NotesFiles.c_str()); + if (!this->Impl->NotesFiles.empty()) { + this->GenerateNotesFile(this->Impl->NotesFiles.c_str()); } } - if (this->Parts[PartSubmit]) { + if (this->Impl->Parts[PartSubmit]) { this->UpdateCTestConfiguration(); - if (this->GetHandler("submit")->ProcessHandler() < 0) { + if (this->GetSubmitHandler()->ProcessHandler() < 0) { res |= cmCTest::SUBMIT_ERRORS; } } @@ -977,10 +1020,10 @@ int cmCTest::ProcessSteps() std::string cmCTest::GetTestModelString() { - if (!this->SpecificTrack.empty()) { - return this->SpecificTrack; + if (!this->Impl->SpecificTrack.empty()) { + return this->Impl->SpecificTrack; } - switch (this->TestModel) { + switch (this->Impl->TestModel) { case cmCTest::NIGHTLY: return "Nightly"; case cmCTest::CONTINUOUS: @@ -1139,8 +1182,9 @@ int cmCTest::RunTest(std::vector<const char*> argv, std::string* output, if (timeout != cmCTest::MaxDuration()) { timeout -= std::chrono::minutes(2); } - if (this->TimeOut > cmDuration::zero() && this->TimeOut < timeout) { - timeout = this->TimeOut; + if (this->Impl->TimeOut > cmDuration::zero() && + this->Impl->TimeOut < timeout) { + timeout = this->Impl->TimeOut; } if (testTimeOut > cmDuration::zero() && testTimeOut < this->GetRemainingTimeAllowed()) { @@ -1158,10 +1202,10 @@ int cmCTest::RunTest(std::vector<const char*> argv, std::string* output, : std::to_string(cmDurationTo<unsigned int>(timeout))) << "\n"); if (cmSystemTools::SameFile(argv[0], cmSystemTools::GetCTestCommand()) && - !this->ForceNewCTestProcess) { + !this->Impl->ForceNewCTestProcess) { cmCTest inst; - inst.ConfigType = this->ConfigType; - inst.TimeOut = timeout; + inst.Impl->ConfigType = this->Impl->ConfigType; + inst.Impl->TimeOut = timeout; // Capture output of the child ctest. std::ostringstream oss; @@ -1267,11 +1311,11 @@ int cmCTest::RunTest(std::vector<const char*> argv, std::string* output, if (result == cmsysProcess_State_Exited) { *retVal = cmsysProcess_GetExitValue(cp); - if (*retVal != 0 && this->OutputTestOutputOnTestFailure) { + if (*retVal != 0 && this->Impl->OutputTestOutputOnTestFailure) { OutputTestErrors(tempOutput); } } else if (result == cmsysProcess_State_Exception) { - if (this->OutputTestOutputOnTestFailure) { + if (this->Impl->OutputTestOutputOnTestFailure) { OutputTestErrors(tempOutput); } *retVal = cmsysProcess_GetExitException(cp); @@ -1330,7 +1374,7 @@ std::string cmCTest::SafeBuildIdField(const std::string& value) void cmCTest::StartXML(cmXMLWriter& xml, bool append) { - if (this->CurrentTag.empty()) { + if (this->Impl->CurrentTag.empty()) { cmCTestLog(this, ERROR_MESSAGE, "Current Tag empty, this may mean" " NightlStartTime was not set correctly." @@ -1346,7 +1390,7 @@ void cmCTest::StartXML(cmXMLWriter& xml, bool append) std::string buildname = cmCTest::SafeBuildIdField(this->GetCTestConfiguration("BuildName")); - std::string stamp = cmCTest::SafeBuildIdField(this->CurrentTag + "-" + + std::string stamp = cmCTest::SafeBuildIdField(this->Impl->CurrentTag + "-" + this->GetTestModelString()); std::string site = cmCTest::SafeBuildIdField(this->GetCTestConfiguration("Site")); @@ -1394,8 +1438,7 @@ void cmCTest::StartXML(cmXMLWriter& xml, bool append) void cmCTest::AddSiteProperties(cmXMLWriter& xml) { - cmCTestScriptHandler* ch = - static_cast<cmCTestScriptHandler*>(this->GetHandler("script")); + cmCTestScriptHandler* ch = this->GetScriptHandler(); cmake* cm = ch->GetCMake(); // if no CMake then this is the old style script and props like // this will not work anyway. @@ -1465,7 +1508,7 @@ void cmCTest::EndXML(cmXMLWriter& xml) } int cmCTest::GenerateCTestNotesOutput(cmXMLWriter& xml, - const cmCTest::VectorOfStrings& files) + std::vector<std::string> const& files) { std::string buildname = cmCTest::SafeBuildIdField(this->GetCTestConfiguration("BuildName")); @@ -1477,7 +1520,7 @@ int cmCTest::GenerateCTestNotesOutput(cmXMLWriter& xml, xml.StartElement("Site"); xml.Attribute("BuildName", buildname); xml.Attribute("BuildStamp", - this->CurrentTag + "-" + this->GetTestModelString()); + this->Impl->CurrentTag + "-" + this->GetTestModelString()); xml.Attribute("Name", this->GetCTestConfiguration("Site")); xml.Attribute("Generator", std::string("ctest") + cmVersion::GetCMakeVersion()); @@ -1515,10 +1558,10 @@ int cmCTest::GenerateCTestNotesOutput(cmXMLWriter& xml, return 1; } -int cmCTest::GenerateNotesFile(const VectorOfStrings& files) +int cmCTest::GenerateNotesFile(std::vector<std::string> const& files) { cmGeneratedFileStream ofs; - if (!this->OpenOutputFile(this->CurrentTag, "Notes.xml", ofs)) { + if (!this->OpenOutputFile(this->Impl->CurrentTag, "Notes.xml", ofs)) { cmCTestLog(this, ERROR_MESSAGE, "Cannot open notes file" << std::endl); return 1; } @@ -1533,11 +1576,10 @@ int cmCTest::GenerateNotesFile(const char* cfiles) return 1; } - VectorOfStrings files; - cmCTestLog(this, OUTPUT, "Create notes file" << std::endl); - files = cmSystemTools::SplitString(cfiles, ';'); + std::vector<std::string> const files = + cmSystemTools::SplitString(cfiles, ';'); if (files.empty()) { return 1; } @@ -1548,14 +1590,14 @@ int cmCTest::GenerateNotesFile(const char* cfiles) int cmCTest::GenerateDoneFile() { cmGeneratedFileStream ofs; - if (!this->OpenOutputFile(this->CurrentTag, "Done.xml", ofs)) { + if (!this->OpenOutputFile(this->Impl->CurrentTag, "Done.xml", ofs)) { cmCTestLog(this, ERROR_MESSAGE, "Cannot open done file" << std::endl); return 1; } cmXMLWriter xml(ofs); xml.StartDocument(); xml.StartElement("Done"); - xml.Element("buildId", this->BuildID); + xml.Element("buildId", this->Impl->BuildID); xml.Element("time", std::chrono::system_clock::now()); xml.EndElement(); // Done xml.EndDocument(); @@ -1604,7 +1646,7 @@ std::string cmCTest::Base64EncodeFile(std::string const& file) return std::string(&encoded_buffer[0], rlen); } -bool cmCTest::SubmitExtraFiles(const VectorOfStrings& files) +bool cmCTest::SubmitExtraFiles(std::vector<std::string> const& files) { for (std::string const& file : files) { if (!cmSystemTools::FileExists(file)) { @@ -1624,11 +1666,10 @@ bool cmCTest::SubmitExtraFiles(const char* cfiles) return true; } - VectorOfStrings files; - cmCTestLog(this, OUTPUT, "Submit extra files" << std::endl); - files = cmSystemTools::SplitString(cfiles, ';'); + std::vector<std::string> const files = + cmSystemTools::SplitString(cfiles, ';'); if (files.empty()) { return true; } @@ -1796,17 +1837,17 @@ bool cmCTest::HandleCommandLineArguments(size_t& i, { std::string arg = args[i]; if (this->CheckArgument(arg, "-F")) { - this->Failover = true; + this->Impl->Failover = true; } if (this->CheckArgument(arg, "-j", "--parallel") && i < args.size() - 1) { i++; int plevel = atoi(args[i].c_str()); this->SetParallelLevel(plevel); - this->ParallelLevelSetInCli = true; + this->Impl->ParallelLevelSetInCli = true; } else if (arg.find("-j") == 0) { int plevel = atoi(arg.substr(2).c_str()); this->SetParallelLevel(plevel); - this->ParallelLevelSetInCli = true; + this->Impl->ParallelLevelSetInCli = true; } if (this->CheckArgument(arg, "--repeat-until-fail")) { if (i >= args.size() - 1) { @@ -1820,9 +1861,9 @@ bool cmCTest::HandleCommandLineArguments(size_t& i, "'--repeat-until-fail' given non-integer value '" + args[i] + "'"; return false; } - this->RepeatTests = static_cast<int>(repeat); + this->Impl->RepeatTests = static_cast<int>(repeat); if (repeat > 1) { - this->RepeatUntilFail = true; + this->Impl->RepeatUntilFail = true; } } @@ -1838,21 +1879,21 @@ bool cmCTest::HandleCommandLineArguments(size_t& i, } if (this->CheckArgument(arg, "--no-compress-output")) { - this->CompressTestOutput = false; + this->Impl->CompressTestOutput = false; } if (this->CheckArgument(arg, "--print-labels")) { - this->PrintLabels = true; + this->Impl->PrintLabels = true; } if (this->CheckArgument(arg, "--http1.0")) { - this->UseHTTP10 = true; + this->Impl->UseHTTP10 = true; } if (this->CheckArgument(arg, "--timeout") && i < args.size() - 1) { i++; auto timeout = cmDuration(atof(args[i].c_str())); - this->GlobalTimeout = timeout; + this->Impl->GlobalTimeout = timeout; } if (this->CheckArgument(arg, "--stop-time") && i < args.size() - 1) { @@ -1867,47 +1908,44 @@ bool cmCTest::HandleCommandLineArguments(size_t& i, } if (this->CheckArgument(arg, "--debug")) { - this->Debug = true; - this->ShowLineNumbers = true; + this->Impl->Debug = true; + this->Impl->ShowLineNumbers = true; } if (this->CheckArgument(arg, "--track") && i < args.size() - 1) { i++; - this->SpecificTrack = args[i]; + this->Impl->SpecificTrack = args[i]; } if (this->CheckArgument(arg, "--show-line-numbers")) { - this->ShowLineNumbers = true; + this->Impl->ShowLineNumbers = true; } if (this->CheckArgument(arg, "--no-label-summary")) { - this->LabelSummary = false; + this->Impl->LabelSummary = false; } if (this->CheckArgument(arg, "--no-subproject-summary")) { - this->SubprojectSummary = false; + this->Impl->SubprojectSummary = false; } if (this->CheckArgument(arg, "-Q", "--quiet")) { - this->Quiet = true; + this->Impl->Quiet = true; } if (this->CheckArgument(arg, "--progress")) { - this->TestProgressOutput = true; + this->Impl->TestProgressOutput = true; } if (this->CheckArgument(arg, "-V", "--verbose")) { - this->Verbose = true; + this->Impl->Verbose = true; } if (this->CheckArgument(arg, "-VV", "--extra-verbose")) { - this->ExtraVerbose = true; - this->Verbose = true; + this->Impl->ExtraVerbose = true; + this->Impl->Verbose = true; } if (this->CheckArgument(arg, "--output-on-failure")) { - this->OutputTestOutputOnTestFailure = true; + this->Impl->OutputTestOutputOnTestFailure = true; } if (this->CheckArgument(arg, "--test-output-size-passed") && i < args.size() - 1) { i++; long outputSize; if (cmSystemTools::StringToLong(args[i].c_str(), &outputSize)) { - if (cmCTestTestHandler* pCTestTestHandler = - static_cast<cmCTestTestHandler*>(this->TestingHandlers["test"])) { - pCTestTestHandler->SetTestOutputSizePassed(int(outputSize)); - } + this->Impl->TestHandler.SetTestOutputSizePassed(int(outputSize)); } else { cmCTestLog(this, WARNING, "Invalid value for '--test-output-size-passed': " << args[i] @@ -1919,10 +1957,7 @@ bool cmCTest::HandleCommandLineArguments(size_t& i, i++; long outputSize; if (cmSystemTools::StringToLong(args[i].c_str(), &outputSize)) { - if (cmCTestTestHandler* pCTestTestHandler = - static_cast<cmCTestTestHandler*>(this->TestingHandlers["test"])) { - pCTestTestHandler->SetTestOutputSizeFailed(int(outputSize)); - } + this->Impl->TestHandler.SetTestOutputSizeFailed(int(outputSize)); } else { cmCTestLog(this, WARNING, "Invalid value for '--test-output-size-failed': " << args[i] @@ -1930,10 +1965,10 @@ bool cmCTest::HandleCommandLineArguments(size_t& i, } } if (this->CheckArgument(arg, "-N", "--show-only")) { - this->ShowOnly = true; + this->Impl->ShowOnly = true; } if (cmSystemTools::StringStartsWith(arg.c_str(), "--show-only=")) { - this->ShowOnly = true; + this->Impl->ShowOnly = true; // Check if a specific format is requested. Defaults to human readable // text. @@ -1941,9 +1976,9 @@ bool cmCTest::HandleCommandLineArguments(size_t& i, std::string format = arg.substr(argWithFormat.length()); if (format == "json-v1") { // Force quiet mode so the only output is the json object model. - this->Quiet = true; - this->OutputAsJson = true; - this->OutputAsJsonVersion = 1; + this->Impl->Quiet = true; + this->Impl->OutputAsJson = true; + this->Impl->OutputAsJsonVersion = 1; } else if (format != "human") { errormsg = "'--show-only=' given unknown value '" + format + "'"; return false; @@ -1956,25 +1991,25 @@ bool cmCTest::HandleCommandLineArguments(size_t& i, } if (this->CheckArgument(arg, "--tomorrow-tag")) { - this->TomorrowTag = true; + this->Impl->TomorrowTag = true; } if (this->CheckArgument(arg, "--force-new-ctest-process")) { - this->ForceNewCTestProcess = true; + this->Impl->ForceNewCTestProcess = true; } if (this->CheckArgument(arg, "-W", "--max-width") && i < args.size() - 1) { i++; - this->MaxTestNameWidth = atoi(args[i].c_str()); + this->Impl->MaxTestNameWidth = atoi(args[i].c_str()); } if (this->CheckArgument(arg, "--interactive-debug-mode") && i < args.size() - 1) { i++; - this->InteractiveDebugMode = cmSystemTools::IsOn(args[i]); + this->Impl->InteractiveDebugMode = cmSystemTools::IsOn(args[i]); } if (this->CheckArgument(arg, "--submit-index") && i < args.size() - 1) { i++; - this->SubmitIndex = atoi(args[i].c_str()); - if (this->SubmitIndex < 0) { - this->SubmitIndex = 0; + this->Impl->SubmitIndex = atoi(args[i].c_str()); + if (this->Impl->SubmitIndex < 0) { + this->Impl->SubmitIndex = 0; } } @@ -1983,7 +2018,7 @@ bool cmCTest::HandleCommandLineArguments(size_t& i, this->AddCTestConfigurationOverwrite(args[i]); } if (this->CheckArgument(arg, "-A", "--add-notes") && i < args.size() - 1) { - this->ProduceXML = true; + this->Impl->ProduceXML = true; this->SetTest("Notes"); i++; this->SetNotesFiles(args[i].c_str()); @@ -1993,78 +2028,75 @@ bool cmCTest::HandleCommandLineArguments(size_t& i, if (this->CheckArgument(arg, "-I", "--tests-information") && i < args.size() - 1) { i++; - this->GetHandler("test")->SetPersistentOption("TestsToRunInformation", - args[i].c_str()); - this->GetHandler("memcheck") - ->SetPersistentOption("TestsToRunInformation", args[i].c_str()); + this->GetTestHandler()->SetPersistentOption("TestsToRunInformation", + args[i].c_str()); + this->GetMemCheckHandler()->SetPersistentOption("TestsToRunInformation", + args[i].c_str()); } if (this->CheckArgument(arg, "-U", "--union")) { - this->GetHandler("test")->SetPersistentOption("UseUnion", "true"); - this->GetHandler("memcheck")->SetPersistentOption("UseUnion", "true"); + this->GetTestHandler()->SetPersistentOption("UseUnion", "true"); + this->GetMemCheckHandler()->SetPersistentOption("UseUnion", "true"); } if (this->CheckArgument(arg, "-R", "--tests-regex") && i < args.size() - 1) { i++; - this->GetHandler("test")->SetPersistentOption("IncludeRegularExpression", - args[i].c_str()); - this->GetHandler("memcheck") - ->SetPersistentOption("IncludeRegularExpression", args[i].c_str()); + this->GetTestHandler()->SetPersistentOption("IncludeRegularExpression", + args[i].c_str()); + this->GetMemCheckHandler()->SetPersistentOption("IncludeRegularExpression", + args[i].c_str()); } if (this->CheckArgument(arg, "-L", "--label-regex") && i < args.size() - 1) { i++; - this->GetHandler("test")->SetPersistentOption("LabelRegularExpression", - args[i].c_str()); - this->GetHandler("memcheck") - ->SetPersistentOption("LabelRegularExpression", args[i].c_str()); + this->GetTestHandler()->SetPersistentOption("LabelRegularExpression", + args[i].c_str()); + this->GetMemCheckHandler()->SetPersistentOption("LabelRegularExpression", + args[i].c_str()); } if (this->CheckArgument(arg, "-LE", "--label-exclude") && i < args.size() - 1) { i++; - this->GetHandler("test")->SetPersistentOption( + this->GetTestHandler()->SetPersistentOption( + "ExcludeLabelRegularExpression", args[i].c_str()); + this->GetMemCheckHandler()->SetPersistentOption( "ExcludeLabelRegularExpression", args[i].c_str()); - this->GetHandler("memcheck") - ->SetPersistentOption("ExcludeLabelRegularExpression", args[i].c_str()); } if (this->CheckArgument(arg, "-E", "--exclude-regex") && i < args.size() - 1) { i++; - this->GetHandler("test")->SetPersistentOption("ExcludeRegularExpression", - args[i].c_str()); - this->GetHandler("memcheck") - ->SetPersistentOption("ExcludeRegularExpression", args[i].c_str()); + this->GetTestHandler()->SetPersistentOption("ExcludeRegularExpression", + args[i].c_str()); + this->GetMemCheckHandler()->SetPersistentOption("ExcludeRegularExpression", + args[i].c_str()); } if (this->CheckArgument(arg, "-FA", "--fixture-exclude-any") && i < args.size() - 1) { i++; - this->GetHandler("test")->SetPersistentOption( + this->GetTestHandler()->SetPersistentOption( + "ExcludeFixtureRegularExpression", args[i].c_str()); + this->GetMemCheckHandler()->SetPersistentOption( "ExcludeFixtureRegularExpression", args[i].c_str()); - this->GetHandler("memcheck") - ->SetPersistentOption("ExcludeFixtureRegularExpression", - args[i].c_str()); } if (this->CheckArgument(arg, "-FS", "--fixture-exclude-setup") && i < args.size() - 1) { i++; - this->GetHandler("test")->SetPersistentOption( + this->GetTestHandler()->SetPersistentOption( + "ExcludeFixtureSetupRegularExpression", args[i].c_str()); + this->GetMemCheckHandler()->SetPersistentOption( "ExcludeFixtureSetupRegularExpression", args[i].c_str()); - this->GetHandler("memcheck") - ->SetPersistentOption("ExcludeFixtureSetupRegularExpression", - args[i].c_str()); } if (this->CheckArgument(arg, "-FC", "--fixture-exclude-cleanup") && i < args.size() - 1) { i++; - this->GetHandler("test")->SetPersistentOption( + this->GetTestHandler()->SetPersistentOption( + "ExcludeFixtureCleanupRegularExpression", args[i].c_str()); + this->GetMemCheckHandler()->SetPersistentOption( "ExcludeFixtureCleanupRegularExpression", args[i].c_str()); - this->GetHandler("memcheck") - ->SetPersistentOption("ExcludeFixtureCleanupRegularExpression", - args[i].c_str()); } if (this->CheckArgument(arg, "--rerun-failed")) { - this->GetHandler("test")->SetPersistentOption("RerunFailed", "true"); - this->GetHandler("memcheck")->SetPersistentOption("RerunFailed", "true"); + this->GetTestHandler()->SetPersistentOption("RerunFailed", "true"); + this->GetMemCheckHandler()->SetPersistentOption("RerunFailed", "true"); } return true; } @@ -2111,10 +2143,9 @@ void cmCTest::HandleScriptArguments(size_t& i, std::vector<std::string>& args, std::string arg = args[i]; if (this->CheckArgument(arg, "-SP", "--script-new-process") && i < args.size() - 1) { - this->RunConfigurationScript = true; + this->Impl->RunConfigurationScript = true; i++; - cmCTestScriptHandler* ch = - static_cast<cmCTestScriptHandler*>(this->GetHandler("script")); + cmCTestScriptHandler* ch = this->GetScriptHandler(); // -SR is an internal argument, -SP should be ignored when it is passed if (!SRArgumentSpecified) { ch->AddConfigurationScript(args[i].c_str(), false); @@ -2123,18 +2154,16 @@ void cmCTest::HandleScriptArguments(size_t& i, std::vector<std::string>& args, if (this->CheckArgument(arg, "-SR", "--script-run") && i < args.size() - 1) { SRArgumentSpecified = true; - this->RunConfigurationScript = true; + this->Impl->RunConfigurationScript = true; i++; - cmCTestScriptHandler* ch = - static_cast<cmCTestScriptHandler*>(this->GetHandler("script")); + cmCTestScriptHandler* ch = this->GetScriptHandler(); ch->AddConfigurationScript(args[i].c_str(), true); } if (this->CheckArgument(arg, "-S", "--script") && i < args.size() - 1) { - this->RunConfigurationScript = true; + this->Impl->RunConfigurationScript = true; i++; - cmCTestScriptHandler* ch = - static_cast<cmCTestScriptHandler*>(this->GetHandler("script")); + cmCTestScriptHandler* ch = this->GetScriptHandler(); // -SR is an internal argument, -S should be ignored when it is passed if (!SRArgumentSpecified) { ch->AddConfigurationScript(args[i].c_str(), true); @@ -2149,7 +2178,7 @@ bool cmCTest::AddVariableDefinition(const std::string& arg) cmStateEnums::CacheEntryType type = cmStateEnums::UNINITIALIZED; if (cmake::ParseCacheEntry(arg, name, value, type)) { - this->Definitions[name] = value; + this->Impl->Definitions[name] = value; return true; } @@ -2165,8 +2194,8 @@ int cmCTest::Run(std::vector<std::string>& args, std::string* output) bool SRArgumentSpecified = false; // copy the command line - this->InitialCommandLineArguments.insert( - this->InitialCommandLineArguments.end(), args.begin(), args.end()); + this->Impl->InitialCommandLineArguments.insert( + this->Impl->InitialCommandLineArguments.end(), args.begin(), args.end()); // process the command line arguments for (size_t i = 1; i < args.size(); ++i) { @@ -2183,7 +2212,7 @@ int cmCTest::Run(std::vector<std::string>& args, std::string* output) // --dashboard: handle a request for a dashboard std::string arg = args[i]; if (this->CheckArgument(arg, "-D", "--dashboard") && i < args.size() - 1) { - this->ProduceXML = true; + this->Impl->ProduceXML = true; i++; std::string targ = args[i]; // AddTestsForDashboard parses the dashboard type and converts it @@ -2219,7 +2248,7 @@ int cmCTest::Run(std::vector<std::string>& args, std::string* output) // --extra-submit if (this->CheckArgument(arg, "--extra-submit") && i < args.size() - 1) { - this->ProduceXML = true; + this->Impl->ProduceXML = true; this->SetTest("Submit"); i++; if (!this->SubmitExtraFiles(args[i].c_str())) { @@ -2234,14 +2263,14 @@ int cmCTest::Run(std::vector<std::string>& args, std::string* output) // --schedule-random if (this->CheckArgument(arg, "--schedule-random")) { - this->ScheduleType = "Random"; + this->Impl->ScheduleType = "Random"; } // pass the argument to all the handlers as well, but i may no longer be // set to what it was originally so I'm not sure this is working as // intended - for (auto& handler : this->TestingHandlers) { - if (!handler.second->ProcessCommandLineArguments(arg, i, args)) { + for (auto& handler : this->Impl->GetTestingHandlers()) { + if (!handler->ProcessCommandLineArguments(arg, i, args)) { cmCTestLog(this, ERROR_MESSAGE, "Problem parsing command line arguments within a handler"); return 0; @@ -2250,7 +2279,7 @@ int cmCTest::Run(std::vector<std::string>& args, std::string* output) } // the close of the for argument loop // handle CTEST_PARALLEL_LEVEL environment variable - if (!this->ParallelLevelSetInCli) { + if (!this->Impl->ParallelLevelSetInCli) { std::string parallel; if (cmSystemTools::GetEnv("CTEST_PARALLEL_LEVEL", parallel)) { int plevel = atoi(parallel.c_str()); @@ -2260,10 +2289,10 @@ int cmCTest::Run(std::vector<std::string>& args, std::string* output) // TestProgressOutput only supported if console supports it and not logging // to a file - this->TestProgressOutput = this->TestProgressOutput && - !this->OutputLogFile && this->ProgressOutputSupportedByConsole(); + this->Impl->TestProgressOutput = this->Impl->TestProgressOutput && + !this->Impl->OutputLogFile && this->ProgressOutputSupportedByConsole(); #ifdef _WIN32 - if (this->TestProgressOutput) { + if (this->Impl->TestProgressOutput) { // Disable output line buffering so we can print content without // a newline. std::setvbuf(stdout, nullptr, _IONBF, 0); @@ -2290,7 +2319,7 @@ bool cmCTest::HandleTestActionArgument(const char* ctestExec, size_t& i, std::string arg = args[i]; if (this->CheckArgument(arg, "-T", "--test-action") && (i < args.size() - 1)) { - this->ProduceXML = true; + this->Impl->ProduceXML = true; i++; if (!this->SetTest(args[i].c_str(), false)) { success = false; @@ -2350,16 +2379,16 @@ int cmCTest::ExecuteTests() { int res; // call process directory - if (this->RunConfigurationScript) { - if (this->ExtraVerbose) { + if (this->Impl->RunConfigurationScript) { + if (this->Impl->ExtraVerbose) { cmCTestLog(this, OUTPUT, "* Extra verbosity turned on" << std::endl); } - for (auto& handler : this->TestingHandlers) { - handler.second->SetVerbose(this->ExtraVerbose); - handler.second->SetSubmitIndex(this->SubmitIndex); + for (auto& handler : this->Impl->GetTestingHandlers()) { + handler->SetVerbose(this->Impl->ExtraVerbose); + handler->SetSubmitIndex(this->Impl->SubmitIndex); } - this->GetHandler("script")->SetVerbose(this->Verbose); - res = this->GetHandler("script")->ProcessHandler(); + this->GetScriptHandler()->SetVerbose(this->Impl->Verbose); + res = this->GetScriptHandler()->ProcessHandler(); if (res != 0) { cmCTestLog(this, DEBUG, "running script failing returning: " << res << std::endl); @@ -2368,11 +2397,11 @@ int cmCTest::ExecuteTests() } else { // What is this? -V seems to be the same as -VV, // and Verbose is always on in this case - this->ExtraVerbose = this->Verbose; - this->Verbose = true; - for (auto& handler : this->TestingHandlers) { - handler.second->SetVerbose(this->Verbose); - handler.second->SetSubmitIndex(this->SubmitIndex); + this->Impl->ExtraVerbose = this->Impl->Verbose; + this->Impl->Verbose = true; + for (auto& handler : this->Impl->GetTestingHandlers()) { + handler->SetVerbose(this->Impl->Verbose); + handler->SetSubmitIndex(this->Impl->SubmitIndex); } std::string cwd = cmSystemTools::GetCurrentWorkingDirectory(); if (!this->Initialize(cwd.c_str(), nullptr)) { @@ -2393,9 +2422,8 @@ int cmCTest::ExecuteTests() int cmCTest::RunCMakeAndTest(std::string* output) { - this->Verbose = true; - cmCTestBuildAndTestHandler* handler = - static_cast<cmCTestBuildAndTestHandler*>(this->GetHandler("buildtest")); + this->Impl->Verbose = true; + cmCTestBuildAndTestHandler* handler = this->GetBuildAndTestHandler(); int retv = handler->ProcessHandler(); *output = handler->GetOutput(); #ifdef CMAKE_BUILD_WITH_CMAKE @@ -2413,7 +2441,12 @@ void cmCTest::SetNotesFiles(const char* notes) if (!notes) { return; } - this->NotesFiles = notes; + this->Impl->NotesFiles = notes; +} + +std::chrono::system_clock::time_point cmCTest::GetStopTime() const +{ + return this->Impl->StopTime; } void cmCTest::SetStopTime(std::string const& time_str) @@ -2443,21 +2476,29 @@ void cmCTest::SetStopTime(std::string const& time_str) time_t stop_time = curl_getdate(buf, ¤t_time); if (stop_time == -1) { - this->StopTime = std::chrono::system_clock::time_point(); + this->Impl->StopTime = std::chrono::system_clock::time_point(); return; } - this->StopTime = std::chrono::system_clock::from_time_t(stop_time); + this->Impl->StopTime = std::chrono::system_clock::from_time_t(stop_time); if (stop_time < current_time) { - this->StopTime += std::chrono::hours(24); + this->Impl->StopTime += std::chrono::hours(24); } } +std::string cmCTest::GetScheduleType() const +{ + return this->Impl->ScheduleType; +} + +void cmCTest::SetScheduleType(std::string const& type) +{ + this->Impl->ScheduleType = type; +} + int cmCTest::ReadCustomConfigurationFileTree(const char* dir, cmMakefile* mf) { bool found = false; - VectorOfStrings dirs; - VectorOfStrings ndirs; cmCTestLog(this, DEBUG, "* Read custom CTest configuration directory: " << dir << std::endl); @@ -2505,7 +2546,7 @@ int cmCTest::ReadCustomConfigurationFileTree(const char* dir, cmMakefile* mf) } if (found) { - for (auto& handler : this->TestingHandlers) { + for (auto& handler : this->Impl->GetNamedTestingHandlers()) { cmCTestLog(this, DEBUG, "* Read custom CTest configuration vectors for handler: " << handler.first << " (" << handler.second << ")" @@ -2596,16 +2637,16 @@ std::string cmCTest::GetShortPathToFile(const char* cfname) std::string cmCTest::GetCTestConfiguration(const std::string& name) { - if (this->CTestConfigurationOverwrites.find(name) != - this->CTestConfigurationOverwrites.end()) { - return this->CTestConfigurationOverwrites[name]; + if (this->Impl->CTestConfigurationOverwrites.find(name) != + this->Impl->CTestConfigurationOverwrites.end()) { + return this->Impl->CTestConfigurationOverwrites[name]; } - return this->CTestConfiguration[name]; + return this->Impl->CTestConfiguration[name]; } void cmCTest::EmptyCTestConfiguration() { - this->CTestConfiguration.clear(); + this->Impl->CTestConfiguration.clear(); } void cmCTest::SetCTestConfiguration(const char* name, const char* value, @@ -2620,10 +2661,10 @@ void cmCTest::SetCTestConfiguration(const char* name, const char* value, return; } if (!value) { - this->CTestConfiguration.erase(name); + this->Impl->CTestConfiguration.erase(name); return; } - this->CTestConfiguration[name] = value; + this->Impl->CTestConfiguration[name] = value; } std::string cmCTest::GetSubmitURL() @@ -2654,69 +2695,190 @@ std::string cmCTest::GetSubmitURL() std::string cmCTest::GetCurrentTag() { - return this->CurrentTag; + return this->Impl->CurrentTag; } std::string cmCTest::GetBinaryDir() { - return this->BinaryDir; + return this->Impl->BinaryDir; } std::string const& cmCTest::GetConfigType() { - return this->ConfigType; + return this->Impl->ConfigType; +} + +cmDuration cmCTest::GetTimeOut() const +{ + return this->Impl->TimeOut; +} + +void cmCTest::SetTimeOut(cmDuration t) +{ + this->Impl->TimeOut = t; +} + +cmDuration cmCTest::GetGlobalTimeout() const +{ + return this->Impl->GlobalTimeout; } bool cmCTest::GetShowOnly() { - return this->ShowOnly; + return this->Impl->ShowOnly; } bool cmCTest::GetOutputAsJson() { - return this->OutputAsJson; + return this->Impl->OutputAsJson; } int cmCTest::GetOutputAsJsonVersion() { - return this->OutputAsJsonVersion; + return this->Impl->OutputAsJsonVersion; +} + +bool cmCTest::ShouldUseHTTP10() const +{ + return this->Impl->UseHTTP10; +} + +bool cmCTest::ShouldPrintLabels() const +{ + return this->Impl->PrintLabels; } int cmCTest::GetMaxTestNameWidth() const { - return this->MaxTestNameWidth; + return this->Impl->MaxTestNameWidth; +} + +void cmCTest::SetMaxTestNameWidth(int w) +{ + this->Impl->MaxTestNameWidth = w; } void cmCTest::SetProduceXML(bool v) { - this->ProduceXML = v; + this->Impl->ProduceXML = v; } bool cmCTest::GetProduceXML() { - return this->ProduceXML; + return this->Impl->ProduceXML; +} + +std::vector<std::string>& cmCTest::GetInitialCommandLineArguments() +{ + return this->Impl->InitialCommandLineArguments; } const char* cmCTest::GetSpecificTrack() { - if (this->SpecificTrack.empty()) { + if (this->Impl->SpecificTrack.empty()) { return nullptr; } - return this->SpecificTrack.c_str(); + return this->Impl->SpecificTrack.c_str(); } void cmCTest::SetSpecificTrack(const char* track) { if (!track) { - this->SpecificTrack.clear(); + this->Impl->SpecificTrack.clear(); return; } - this->SpecificTrack = track; + this->Impl->SpecificTrack = track; +} + +void cmCTest::SetFailover(bool failover) +{ + this->Impl->Failover = failover; +} + +bool cmCTest::GetFailover() const +{ + return this->Impl->Failover; +} + +bool cmCTest::GetTestProgressOutput() const +{ + return this->Impl->TestProgressOutput; +} + +bool cmCTest::GetVerbose() const +{ + return this->Impl->Verbose; +} + +bool cmCTest::GetExtraVerbose() const +{ + return this->Impl->ExtraVerbose; +} + +void cmCTest::SetStreams(std::ostream* out, std::ostream* err) +{ + this->Impl->StreamOut = out; + this->Impl->StreamErr = err; +} + +bool cmCTest::GetLabelSummary() const +{ + return this->Impl->LabelSummary; +} + +bool cmCTest::GetSubprojectSummary() const +{ + return this->Impl->SubprojectSummary; +} + +bool cmCTest::GetOutputTestOutputOnTestFailure() const +{ + return this->Impl->OutputTestOutputOnTestFailure; +} + +const std::map<std::string, std::string>& cmCTest::GetDefinitions() const +{ + return this->Impl->Definitions; +} + +int cmCTest::GetTestRepeat() const +{ + return this->Impl->RepeatTests; +} + +bool cmCTest::GetRepeatUntilFail() const +{ + return this->Impl->RepeatUntilFail; +} + +void cmCTest::SetBuildID(const std::string& id) +{ + this->Impl->BuildID = id; +} + +std::string cmCTest::GetBuildID() const +{ + return this->Impl->BuildID; } void cmCTest::AddSubmitFile(Part part, const char* name) { - this->Parts[part].SubmitFiles.emplace_back(name); + this->Impl->Parts[part].SubmitFiles.emplace_back(name); +} + +std::vector<std::string> const& cmCTest::GetSubmitFiles(Part part) const +{ + return this->Impl->Parts[part].SubmitFiles; +} + +void cmCTest::ClearSubmitFiles(Part part) +{ + this->Impl->Parts[part].SubmitFiles.clear(); +} + +void cmCTest::SetSuppressUpdatingCTestConfiguration(bool val) +{ + this->Impl->SuppressUpdatingCTestConfiguration = val; } void cmCTest::AddCTestConfigurationOverwrite(const std::string& overStr) @@ -2732,14 +2894,14 @@ void cmCTest::AddCTestConfigurationOverwrite(const std::string& overStr) } std::string key = overStr.substr(0, epos); std::string value = overStr.substr(epos + 1); - this->CTestConfigurationOverwrites[key] = value; + this->Impl->CTestConfigurationOverwrites[key] = value; } void cmCTest::SetConfigType(const char* ct) { - this->ConfigType = ct ? ct : ""; - cmSystemTools::ReplaceString(this->ConfigType, ".\\", ""); - std::string confTypeEnv = "CMAKE_CONFIG_TYPE=" + this->ConfigType; + this->Impl->ConfigType = ct ? ct : ""; + cmSystemTools::ReplaceString(this->Impl->ConfigType, ".\\", ""); + std::string confTypeEnv = "CMAKE_CONFIG_TYPE=" + this->Impl->ConfigType; cmSystemTools::PutEnv(confTypeEnv); } @@ -2805,12 +2967,12 @@ bool cmCTest::RunCommand(std::vector<std::string> const& args, done = true; } if ((res == cmsysProcess_Pipe_STDOUT || res == cmsysProcess_Pipe_STDERR) && - this->ExtraVerbose) { + this->Impl->ExtraVerbose) { processOutput.DecodeText(data, length, strdata); cmSystemTools::Stdout(strdata); } } - if (this->ExtraVerbose) { + if (this->Impl->ExtraVerbose) { processOutput.DecodeText(std::string(), strdata); if (!strdata.empty()) { cmSystemTools::Stdout(strdata); @@ -2859,12 +3021,12 @@ bool cmCTest::RunCommand(std::vector<std::string> const& args, void cmCTest::SetOutputLogFileName(const char* name) { - if (this->OutputLogFile) { - delete this->OutputLogFile; - this->OutputLogFile = nullptr; + if (this->Impl->OutputLogFile) { + delete this->Impl->OutputLogFile; + this->Impl->OutputLogFile = nullptr; } if (name) { - this->OutputLogFile = new cmGeneratedFileStream(name); + this->Impl->OutputLogFile = new cmGeneratedFileStream(name); } } @@ -2880,18 +3042,11 @@ static const char* cmCTestStringLogType[] = { "DEBUG", #define cmCTestLogOutputFileLine(stream) \ do { \ - if (this->ShowLineNumbers) { \ + if (this->Impl->ShowLineNumbers) { \ (stream) << std::endl << file << ":" << line << " "; \ } \ } while (false) -void cmCTest::InitStreams() -{ - // By default we write output to the process output streams. - this->StreamOut = &std::cout; - this->StreamErr = &std::cerr; -} - void cmCTest::Log(int logType, const char* file, int line, const char* msg, bool suppress) { @@ -2902,53 +3057,53 @@ void cmCTest::Log(int logType, const char* file, int line, const char* msg, return; } if (logType == cmCTest::HANDLER_PROGRESS_OUTPUT && - (this->Debug || this->ExtraVerbose)) { + (this->Impl->Debug || this->Impl->ExtraVerbose)) { return; } - if (this->OutputLogFile) { + if (this->Impl->OutputLogFile) { bool display = true; - if (logType == cmCTest::DEBUG && !this->Debug) { + if (logType == cmCTest::DEBUG && !this->Impl->Debug) { display = false; } - if (logType == cmCTest::HANDLER_VERBOSE_OUTPUT && !this->Debug && - !this->ExtraVerbose) { + if (logType == cmCTest::HANDLER_VERBOSE_OUTPUT && !this->Impl->Debug && + !this->Impl->ExtraVerbose) { display = false; } if (display) { - cmCTestLogOutputFileLine(*this->OutputLogFile); - if (logType != this->OutputLogFileLastTag) { - *this->OutputLogFile << "["; + cmCTestLogOutputFileLine(*this->Impl->OutputLogFile); + if (logType != this->Impl->OutputLogFileLastTag) { + *this->Impl->OutputLogFile << "["; if (logType >= OTHER || logType < 0) { - *this->OutputLogFile << "OTHER"; + *this->Impl->OutputLogFile << "OTHER"; } else { - *this->OutputLogFile << cmCTestStringLogType[logType]; + *this->Impl->OutputLogFile << cmCTestStringLogType[logType]; } - *this->OutputLogFile << "] " << std::endl << std::flush; + *this->Impl->OutputLogFile << "] " << std::endl << std::flush; } - *this->OutputLogFile << msg << std::flush; - if (logType != this->OutputLogFileLastTag) { - *this->OutputLogFile << std::endl << std::flush; - this->OutputLogFileLastTag = logType; + *this->Impl->OutputLogFile << msg << std::flush; + if (logType != this->Impl->OutputLogFileLastTag) { + *this->Impl->OutputLogFile << std::endl << std::flush; + this->Impl->OutputLogFileLastTag = logType; } } } - if (!this->Quiet) { - std::ostream& out = *this->StreamOut; - std::ostream& err = *this->StreamErr; + if (!this->Impl->Quiet) { + std::ostream& out = *this->Impl->StreamOut; + std::ostream& err = *this->Impl->StreamErr; if (logType == HANDLER_TEST_PROGRESS_OUTPUT) { - if (this->TestProgressOutput) { + if (this->Impl->TestProgressOutput) { cmCTestLogOutputFileLine(out); - if (this->FlushTestProgressLine) { + if (this->Impl->FlushTestProgressLine) { printf("\r"); - this->FlushTestProgressLine = false; + this->Impl->FlushTestProgressLine = false; out.flush(); } std::string msg_str{ msg }; auto const lineBreakIt = msg_str.find('\n'); if (lineBreakIt != std::string::npos) { - this->FlushTestProgressLine = true; + this->Impl->FlushTestProgressLine = true; msg_str.erase(std::remove(msg_str.begin(), msg_str.end(), '\n'), msg_str.end()); } @@ -2965,7 +3120,7 @@ void cmCTest::Log(int logType, const char* file, int line, const char* msg, switch (logType) { case DEBUG: - if (this->Debug) { + if (this->Impl->Debug) { cmCTestLogOutputFileLine(out); out << msg; out.flush(); @@ -2973,14 +3128,14 @@ void cmCTest::Log(int logType, const char* file, int line, const char* msg, break; case OUTPUT: case HANDLER_OUTPUT: - if (this->Debug || this->Verbose) { + if (this->Impl->Debug || this->Impl->Verbose) { cmCTestLogOutputFileLine(out); out << msg; out.flush(); } break; case HANDLER_VERBOSE_OUTPUT: - if (this->Debug || this->ExtraVerbose) { + if (this->Impl->Debug || this->Impl->ExtraVerbose) { cmCTestLogOutputFileLine(out); out << msg; out.flush(); @@ -3007,7 +3162,7 @@ void cmCTest::Log(int logType, const char* file, int line, const char* msg, std::string cmCTest::GetColorCode(Color color) const { - if (this->OutputColorCode) { + if (this->Impl->OutputColorCode) { #if defined(_WIN32) // Not supported on Windows static_cast<void>(color); @@ -3021,14 +3176,7 @@ std::string cmCTest::GetColorCode(Color color) const cmDuration cmCTest::GetRemainingTimeAllowed() { - if (!this->GetHandler("script")) { - return cmCTest::MaxDuration(); - } - - cmCTestScriptHandler* ch = - static_cast<cmCTestScriptHandler*>(this->GetHandler("script")); - - return ch->GetRemainingTimeAllowed(); + return this->GetScriptHandler()->GetRemainingTimeAllowed(); } cmDuration cmCTest::MaxDuration() @@ -3038,10 +3186,7 @@ cmDuration cmCTest::MaxDuration() void cmCTest::SetRunCurrentScript(bool value) { - cmCTestScriptHandler* ch = - static_cast<cmCTestScriptHandler*>(this->GetHandler("script")); - - ch->SetRunCurrentScript(value); + this->GetScriptHandler()->SetRunCurrentScript(value); } void cmCTest::OutputTestErrors(std::vector<char> const& process_output) diff --git a/Source/cmCTest.h b/Source/cmCTest.h index a765fed..d300c33 100644 --- a/Source/cmCTest.h +++ b/Source/cmCTest.h @@ -10,13 +10,22 @@ #include <chrono> #include <map> -#include <set> +#include <memory> // IWYU pragma: keep #include <sstream> #include <string> #include <time.h> #include <vector> -class cmCTestGenericHandler; +class cmCTestBuildHandler; +class cmCTestBuildAndTestHandler; +class cmCTestCoverageHandler; +class cmCTestScriptHandler; +class cmCTestTestHandler; +class cmCTestUpdateHandler; +class cmCTestConfigureHandler; +class cmCTestMemCheckHandler; +class cmCTestSubmitHandler; +class cmCTestUploadHandler; class cmCTestStartCommand; class cmGeneratedFileStream; class cmMakefile; @@ -31,9 +40,6 @@ class cmXMLWriter; */ class cmCTest { - friend class cmCTestRunTest; - friend class cmCTestMultiProcessHandler; - public: typedef cmProcessOutput::Encoding Encoding; /** Enumerate parts of the testing and submission process. */ @@ -54,44 +60,10 @@ public: PartCount // Update names in constructor when adding a part }; - /** Representation of one part. */ - struct PartInfo - { - void SetName(const std::string& name) { this->Name = name; } - const std::string& GetName() const { return this->Name; } - - void Enable() { this->Enabled = true; } - explicit operator bool() const { return this->Enabled; } - - std::vector<std::string> SubmitFiles; - - private: - bool Enabled = false; - std::string Name; - }; -#ifdef CMAKE_BUILD_WITH_CMAKE - enum HTTPMethod - { - HTTP_GET, - HTTP_POST, - HTTP_PUT - }; - - /** - * Perform an HTTP request. - */ - static int HTTPRequest(std::string url, HTTPMethod method, - std::string& response, std::string const& fields = "", - std::string const& putFile = "", int timeout = 0); -#endif - /** Get a testing part id from its string name. Returns PartCount if the string does not name a valid part. */ Part GetPartFromName(const char* name); - typedef std::vector<std::string> VectorOfStrings; - typedef std::set<std::string> SetOfStrings; - /** Process Command line arguments */ int Run(std::vector<std::string>&, std::string* output = nullptr); @@ -128,7 +100,7 @@ public: /** * Is the tomorrow tag set? */ - bool GetTomorrowTag() { return this->TomorrowTag; } + bool GetTomorrowTag() const; /** * Try to run tests of the project @@ -137,16 +109,16 @@ public: /** what is the configuration type, e.g. Debug, Release etc. */ std::string const& GetConfigType(); - cmDuration GetTimeOut() { return this->TimeOut; } - void SetTimeOut(cmDuration t) { this->TimeOut = t; } + cmDuration GetTimeOut() const; + void SetTimeOut(cmDuration t); - cmDuration GetGlobalTimeout() { return this->GlobalTimeout; } + cmDuration GetGlobalTimeout() const; /** how many test to run at the same time */ - int GetParallelLevel() { return this->ParallelLevel; } + int GetParallelLevel() const; void SetParallelLevel(int); - unsigned long GetTestLoad() { return this->TestLoad; } + unsigned long GetTestLoad() const; void SetTestLoad(unsigned long); /** @@ -164,7 +136,7 @@ public: * Set the cmake test mode (experimental, nightly, continuous). */ void SetTestModel(int mode); - int GetTestModel() { return this->TestModel; } + int GetTestModel() const; std::string GetTestModelString(); static int GetTestModelFromString(const char* str); @@ -222,26 +194,23 @@ public: int GetOutputAsJsonVersion(); - bool ShouldUseHTTP10() { return this->UseHTTP10; } + bool ShouldUseHTTP10() const; - bool ShouldPrintLabels() { return this->PrintLabels; } + bool ShouldPrintLabels() const; bool ShouldCompressTestOutput(); bool CompressString(std::string& str); - std::chrono::system_clock::time_point GetStopTime() - { - return this->StopTime; - } + std::chrono::system_clock::time_point GetStopTime() const; void SetStopTime(std::string const& time); /** Used for parallel ctest job scheduling */ - std::string GetScheduleType() { return this->ScheduleType; } - void SetScheduleType(std::string const& type) { this->ScheduleType = type; } + std::string GetScheduleType() const; + void SetScheduleType(std::string const& type); /** The max output width */ int GetMaxTestNameWidth() const; - void SetMaxTestNameWidth(int w) { this->MaxTestNameWidth = w; } + void SetMaxTestNameWidth(int w); /** * Run a single executable command and put the stdout and stderr @@ -335,16 +304,18 @@ public: Encoding encoding = cmProcessOutput::Auto); /** - * Execute handler and return its result. If the handler fails, it returns - * negative value. - */ - int ExecuteHandler(const char* handler); - - /** * Get the handler object */ - cmCTestGenericHandler* GetHandler(const char* handler); - cmCTestGenericHandler* GetInitializedHandler(const char* handler); + cmCTestBuildHandler* GetBuildHandler(); + cmCTestBuildAndTestHandler* GetBuildAndTestHandler(); + cmCTestCoverageHandler* GetCoverageHandler(); + cmCTestScriptHandler* GetScriptHandler(); + cmCTestTestHandler* GetTestHandler(); + cmCTestUpdateHandler* GetUpdateHandler(); + cmCTestConfigureHandler* GetConfigureHandler(); + cmCTestMemCheckHandler* GetMemCheckHandler(); + cmCTestSubmitHandler* GetSubmitHandler(); + cmCTestUploadHandler* GetUploadHandler(); /** * Set the CTest variable from CMake variable @@ -354,9 +325,6 @@ public: const std::string& cmake_var, bool suppress = false); - /** Make string safe to be sent as a URL */ - static std::string MakeURLSafe(const std::string&); - /** Decode a URL to the original string. */ static std::string DecodeURL(const std::string&); @@ -364,10 +332,7 @@ public: * Should ctect configuration be updated. When using new style ctest * script, this should be true. */ - void SetSuppressUpdatingCTestConfiguration(bool val) - { - this->SuppressUpdatingCTestConfiguration = val; - } + void SetSuppressUpdatingCTestConfiguration(bool val); /** * Add overwrite to ctest configuration. @@ -377,14 +342,14 @@ public: void AddCTestConfigurationOverwrite(const std::string& encstr); /** Create XML file that contains all the notes specified */ - int GenerateNotesFile(const VectorOfStrings& files); + int GenerateNotesFile(std::vector<std::string> const& files); /** Create XML file to indicate that build is complete */ int GenerateDoneFile(); /** Submit extra files to the server */ bool SubmitExtraFiles(const char* files); - bool SubmitExtraFiles(const VectorOfStrings& files); + bool SubmitExtraFiles(std::vector<std::string> const& files); /** Set the output log file name */ void SetOutputLogFileName(const char* name); @@ -424,62 +389,52 @@ public: std::string GetColorCode(Color color) const; /** The Build ID is assigned by CDash */ - void SetBuildID(const std::string& id) { this->BuildID = id; } - std::string GetBuildID() { return this->BuildID; } + void SetBuildID(const std::string& id); + std::string GetBuildID() const; /** Add file to be submitted */ void AddSubmitFile(Part part, const char* name); - std::vector<std::string> const& GetSubmitFiles(Part part) - { - return this->Parts[part].SubmitFiles; - } - void ClearSubmitFiles(Part part) { this->Parts[part].SubmitFiles.clear(); } + std::vector<std::string> const& GetSubmitFiles(Part part) const; + void ClearSubmitFiles(Part part); /** * Read the custom configuration files and apply them to the current ctest */ int ReadCustomConfigurationFileTree(const char* dir, cmMakefile* mf); - std::vector<std::string>& GetInitialCommandLineArguments() - { - return this->InitialCommandLineArguments; - } + std::vector<std::string>& GetInitialCommandLineArguments(); /** Set the track to submit to */ void SetSpecificTrack(const char* track); const char* GetSpecificTrack(); - void SetFailover(bool failover) { this->Failover = failover; } - bool GetFailover() { return this->Failover; } + void SetFailover(bool failover); + bool GetFailover() const; - bool GetTestProgressOutput() const { return this->TestProgressOutput; } + bool GetTestProgressOutput() const; - bool GetVerbose() { return this->Verbose; } - bool GetExtraVerbose() { return this->ExtraVerbose; } + bool GetVerbose() const; + bool GetExtraVerbose() const; /** Direct process output to given streams. */ - void SetStreams(std::ostream* out, std::ostream* err) - { - this->StreamOut = out; - this->StreamErr = err; - } + void SetStreams(std::ostream* out, std::ostream* err); + void AddSiteProperties(cmXMLWriter& xml); - bool GetLabelSummary() { return this->LabelSummary; } - bool GetSubprojectSummary() { return this->SubprojectSummary; } + bool GetLabelSummary() const; + bool GetSubprojectSummary() const; std::string GetCostDataFile(); - const std::map<std::string, std::string>& GetDefinitions() - { - return this->Definitions; - } + bool GetOutputTestOutputOnTestFailure() const; + + const std::map<std::string, std::string>& GetDefinitions() const; /** Return the number of times a test should be run */ - int GetTestRepeat() { return this->RepeatTests; } + int GetTestRepeat() const; /** Return true if test should run until fail */ - bool GetRepeatUntilFail() { return this->RepeatUntilFail; } + bool GetRepeatUntilFail() const; void GenerateSubprojectsOutput(cmXMLWriter& xml); std::vector<std::string> GetLabelsForSubprojects(); @@ -487,85 +442,8 @@ public: void SetRunCurrentScript(bool value); private: - int RepeatTests; - bool RepeatUntilFail; - std::string ConfigType; - std::string ScheduleType; - std::chrono::system_clock::time_point StopTime; - bool TestProgressOutput; - bool Verbose; - bool ExtraVerbose; - bool ProduceXML; - bool LabelSummary; - bool SubprojectSummary; - bool UseHTTP10; - bool PrintLabels; - bool Failover; - - bool FlushTestProgressLine; - - bool ForceNewCTestProcess; - - bool RunConfigurationScript; - int GenerateNotesFile(const char* files); - // these are helper classes - typedef std::map<std::string, cmCTestGenericHandler*> t_TestingHandlers; - t_TestingHandlers TestingHandlers; - - bool ShowOnly; - bool OutputAsJson; - int OutputAsJsonVersion; - - /** Map of configuration properties */ - typedef std::map<std::string, std::string> CTestConfigurationMap; - - // TODO: The ctest configuration should be a hierarchy of - // configuration option sources: command-line, script, ini file. - // Then the ini file can get re-loaded whenever it changes without - // affecting any higher-precedence settings. - CTestConfigurationMap CTestConfiguration; - CTestConfigurationMap CTestConfigurationOverwrites; - PartInfo Parts[PartCount]; - typedef std::map<std::string, Part> PartMapType; - PartMapType PartMap; - - std::string CurrentTag; - bool TomorrowTag; - - int TestModel; - std::string SpecificTrack; - - cmDuration TimeOut; - - cmDuration GlobalTimeout; - - int MaxTestNameWidth; - - int ParallelLevel; - bool ParallelLevelSetInCli; - - unsigned long TestLoad; - - int CompatibilityMode; - - // information for the --build-and-test options - std::string BinaryDir; - - std::string NotesFiles; - - bool InteractiveDebugMode; - - bool ShortDateFormat; - - bool CompressXMLFiles; - bool CompressTestOutput; - - void InitStreams(); - std::ostream* StreamOut; - std::ostream* StreamErr; - void BlockTestErrorDiagnostics(); /** @@ -610,7 +488,8 @@ private: bool UpdateCTestConfiguration(); /** Create note from files. */ - int GenerateCTestNotesOutput(cmXMLWriter& xml, const VectorOfStrings& files); + int GenerateCTestNotesOutput(cmXMLWriter& xml, + std::vector<std::string> const& files); /** Check if the argument is the one specified */ bool CheckArgument(const std::string& arg, const char* varg1, @@ -630,25 +509,8 @@ private: int RunCMakeAndTest(std::string* output); int ExecuteTests(); - bool SuppressUpdatingCTestConfiguration; - - bool Debug; - bool ShowLineNumbers; - bool Quiet; - - std::string BuildID; - - std::vector<std::string> InitialCommandLineArguments; - - int SubmitIndex; - - cmGeneratedFileStream* OutputLogFile; - int OutputLogFileLastTag; - - bool OutputTestOutputOnTestFailure; - bool OutputColorCode; - - std::map<std::string, std::string> Definitions; + struct Private; + std::unique_ptr<Private> Impl; }; class cmCTestLogWrite diff --git a/Source/ctest.cxx b/Source/ctest.cxx index 4a2531a..461021b 100644 --- a/Source/ctest.cxx +++ b/Source/ctest.cxx @@ -191,8 +191,7 @@ int main(int argc, char const* const* argv) doc.addCTestStandardDocSections(); if (doc.CheckOptions(argc, argv)) { // Construct and print requested documentation. - cmCTestScriptHandler* ch = - static_cast<cmCTestScriptHandler*>(inst.GetHandler("script")); + cmCTestScriptHandler* ch = inst.GetScriptHandler(); ch->CreateCMake(); doc.SetShowGenerators(false); |