cmCTestSubmitCommand.cxx 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. file Copyright.txt or https://cmake.org/licensing for details. */
  3. #include "cmCTestSubmitCommand.h"
  4. #include "cmCTest.h"
  5. #include "cmCTestSubmitHandler.h"
  6. #include "cmCommand.h"
  7. #include "cmMakefile.h"
  8. #include "cmMessageType.h"
  9. #include "cmSystemTools.h"
  10. #include <sstream>
  11. #include <utility>
  12. #include "cm_memory.hxx"
  13. class cmExecutionStatus;
  14. cmCTestSubmitCommand::cmCTestSubmitCommand()
  15. {
  16. this->PartsMentioned = false;
  17. this->FilesMentioned = false;
  18. this->InternalTest = false;
  19. this->RetryCount = "";
  20. this->RetryDelay = "";
  21. this->CDashUpload = false;
  22. this->Arguments[cts_BUILD_ID] = "BUILD_ID";
  23. this->Last = cts_LAST;
  24. }
  25. /**
  26. * This is a virtual constructor for the command.
  27. */
  28. std::unique_ptr<cmCommand> cmCTestSubmitCommand::Clone()
  29. {
  30. auto ni = cm::make_unique<cmCTestSubmitCommand>();
  31. ni->CTest = this->CTest;
  32. ni->CTestScriptHandler = this->CTestScriptHandler;
  33. return std::unique_ptr<cmCommand>(std::move(ni));
  34. }
  35. cmCTestGenericHandler* cmCTestSubmitCommand::InitializeHandler()
  36. {
  37. const char* submitURL = !this->SubmitURL.empty()
  38. ? this->SubmitURL.c_str()
  39. : this->Makefile->GetDefinition("CTEST_SUBMIT_URL");
  40. if (submitURL) {
  41. this->CTest->SetCTestConfiguration("SubmitURL", submitURL, this->Quiet);
  42. } else {
  43. this->CTest->SetCTestConfigurationFromCMakeVariable(
  44. this->Makefile, "DropMethod", "CTEST_DROP_METHOD", this->Quiet);
  45. this->CTest->SetCTestConfigurationFromCMakeVariable(
  46. this->Makefile, "DropSiteUser", "CTEST_DROP_SITE_USER", this->Quiet);
  47. this->CTest->SetCTestConfigurationFromCMakeVariable(
  48. this->Makefile, "DropSitePassword", "CTEST_DROP_SITE_PASSWORD",
  49. this->Quiet);
  50. this->CTest->SetCTestConfigurationFromCMakeVariable(
  51. this->Makefile, "DropSite", "CTEST_DROP_SITE", this->Quiet);
  52. this->CTest->SetCTestConfigurationFromCMakeVariable(
  53. this->Makefile, "DropLocation", "CTEST_DROP_LOCATION", this->Quiet);
  54. }
  55. this->CTest->SetCTestConfigurationFromCMakeVariable(
  56. this->Makefile, "CurlOptions", "CTEST_CURL_OPTIONS", this->Quiet);
  57. const char* notesFilesVariable =
  58. this->Makefile->GetDefinition("CTEST_NOTES_FILES");
  59. if (notesFilesVariable) {
  60. std::vector<std::string> notesFiles;
  61. cmSystemTools::ExpandListArgument(notesFilesVariable, notesFiles);
  62. this->CTest->GenerateNotesFile(notesFiles);
  63. }
  64. const char* extraFilesVariable =
  65. this->Makefile->GetDefinition("CTEST_EXTRA_SUBMIT_FILES");
  66. if (extraFilesVariable) {
  67. std::vector<std::string> extraFiles;
  68. cmSystemTools::ExpandListArgument(extraFilesVariable, extraFiles);
  69. if (!this->CTest->SubmitExtraFiles(extraFiles)) {
  70. this->SetError("problem submitting extra files.");
  71. return nullptr;
  72. }
  73. }
  74. cmCTestSubmitHandler* handler = this->CTest->GetSubmitHandler();
  75. handler->Initialize();
  76. // If no FILES or PARTS given, *all* PARTS are submitted by default.
  77. //
  78. // If FILES are given, but not PARTS, only the FILES are submitted
  79. // and *no* PARTS are submitted.
  80. // (This is why we select the empty "noParts" set in the
  81. // FilesMentioned block below...)
  82. //
  83. // If PARTS are given, only the selected PARTS are submitted.
  84. //
  85. // If both PARTS and FILES are given, only the selected PARTS *and*
  86. // all the given FILES are submitted.
  87. // If given explicit FILES to submit, pass them to the handler.
  88. //
  89. if (this->FilesMentioned) {
  90. // Intentionally select *no* PARTS. (Pass an empty set.) If PARTS
  91. // were also explicitly mentioned, they will be selected below...
  92. // But FILES with no PARTS mentioned should just submit the FILES
  93. // without any of the default parts.
  94. //
  95. handler->SelectParts(std::set<cmCTest::Part>());
  96. handler->SelectFiles(this->Files);
  97. }
  98. // If a PARTS option was given, select only the named parts for submission.
  99. //
  100. if (this->PartsMentioned) {
  101. handler->SelectParts(this->Parts);
  102. }
  103. // Pass along any HTTPHEADER to the handler if this option was given.
  104. if (!this->HttpHeaders.empty()) {
  105. handler->SetHttpHeaders(this->HttpHeaders);
  106. }
  107. handler->SetOption("RetryDelay", this->RetryDelay.c_str());
  108. handler->SetOption("RetryCount", this->RetryCount.c_str());
  109. handler->SetOption("InternalTest", this->InternalTest ? "ON" : "OFF");
  110. handler->SetQuiet(this->Quiet);
  111. if (this->CDashUpload) {
  112. handler->SetOption("CDashUploadFile", this->CDashUploadFile.c_str());
  113. handler->SetOption("CDashUploadType", this->CDashUploadType.c_str());
  114. }
  115. return handler;
  116. }
  117. bool cmCTestSubmitCommand::InitialPass(std::vector<std::string> const& args,
  118. cmExecutionStatus& status)
  119. {
  120. this->CDashUpload = !args.empty() && args[0] == "CDASH_UPLOAD";
  121. bool ret = this->cmCTestHandlerCommand::InitialPass(args, status);
  122. if (this->Values[cts_BUILD_ID] && *this->Values[cts_BUILD_ID]) {
  123. this->Makefile->AddDefinition(this->Values[cts_BUILD_ID],
  124. this->CTest->GetBuildID());
  125. }
  126. return ret;
  127. }
  128. bool cmCTestSubmitCommand::CheckArgumentKeyword(std::string const& arg)
  129. {
  130. if (this->CDashUpload) {
  131. // Arguments specific to the CDASH_UPLOAD signature.
  132. if (arg == "CDASH_UPLOAD") {
  133. this->ArgumentDoing = ArgumentDoingCDashUpload;
  134. return true;
  135. }
  136. if (arg == "CDASH_UPLOAD_TYPE") {
  137. this->ArgumentDoing = ArgumentDoingCDashUploadType;
  138. return true;
  139. }
  140. } else {
  141. // Arguments that cannot be used with CDASH_UPLOAD.
  142. if (arg == "PARTS") {
  143. this->ArgumentDoing = ArgumentDoingParts;
  144. this->PartsMentioned = true;
  145. return true;
  146. }
  147. if (arg == "FILES") {
  148. this->ArgumentDoing = ArgumentDoingFiles;
  149. this->FilesMentioned = true;
  150. return true;
  151. }
  152. }
  153. // Arguments used by both modes.
  154. if (arg == "HTTPHEADER") {
  155. this->ArgumentDoing = ArgumentDoingHttpHeader;
  156. return true;
  157. }
  158. if (arg == "RETRY_COUNT") {
  159. this->ArgumentDoing = ArgumentDoingRetryCount;
  160. return true;
  161. }
  162. if (arg == "RETRY_DELAY") {
  163. this->ArgumentDoing = ArgumentDoingRetryDelay;
  164. return true;
  165. }
  166. if (arg == "SUBMIT_URL") {
  167. this->ArgumentDoing = ArgumentDoingSubmitURL;
  168. return true;
  169. }
  170. if (arg == "INTERNAL_TEST_CHECKSUM") {
  171. this->InternalTest = true;
  172. return true;
  173. }
  174. // Look for other arguments.
  175. return this->Superclass::CheckArgumentKeyword(arg);
  176. }
  177. bool cmCTestSubmitCommand::CheckArgumentValue(std::string const& arg)
  178. {
  179. // Handle states specific to this command.
  180. if (this->ArgumentDoing == ArgumentDoingParts) {
  181. cmCTest::Part p = this->CTest->GetPartFromName(arg.c_str());
  182. if (p != cmCTest::PartCount) {
  183. this->Parts.insert(p);
  184. } else {
  185. std::ostringstream e;
  186. e << "Part name \"" << arg << "\" is invalid.";
  187. this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
  188. this->ArgumentDoing = ArgumentDoingError;
  189. }
  190. return true;
  191. }
  192. if (this->ArgumentDoing == ArgumentDoingFiles) {
  193. if (cmSystemTools::FileExists(arg)) {
  194. this->Files.insert(arg);
  195. } else {
  196. std::ostringstream e;
  197. e << "File \"" << arg << "\" does not exist. Cannot submit "
  198. << "a non-existent file.";
  199. this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
  200. this->ArgumentDoing = ArgumentDoingError;
  201. }
  202. return true;
  203. }
  204. if (this->ArgumentDoing == ArgumentDoingHttpHeader) {
  205. this->HttpHeaders.push_back(arg);
  206. return true;
  207. }
  208. if (this->ArgumentDoing == ArgumentDoingRetryCount) {
  209. this->RetryCount = arg;
  210. return true;
  211. }
  212. if (this->ArgumentDoing == ArgumentDoingRetryDelay) {
  213. this->RetryDelay = arg;
  214. return true;
  215. }
  216. if (this->ArgumentDoing == ArgumentDoingCDashUpload) {
  217. this->ArgumentDoing = ArgumentDoingNone;
  218. this->CDashUploadFile = arg;
  219. return true;
  220. }
  221. if (this->ArgumentDoing == ArgumentDoingCDashUploadType) {
  222. this->ArgumentDoing = ArgumentDoingNone;
  223. this->CDashUploadType = arg;
  224. return true;
  225. }
  226. if (this->ArgumentDoing == ArgumentDoingSubmitURL) {
  227. this->ArgumentDoing = ArgumentDoingNone;
  228. this->SubmitURL = arg;
  229. return true;
  230. }
  231. // Look for other arguments.
  232. return this->Superclass::CheckArgumentValue(arg);
  233. }