cmCTestHandlerCommand.cxx 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. /*============================================================================
  2. CMake - Cross Platform Makefile Generator
  3. Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
  4. Distributed under the OSI-approved BSD License (the "License");
  5. see accompanying file Copyright.txt for details.
  6. This software is distributed WITHOUT ANY WARRANTY; without even the
  7. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  8. See the License for more information.
  9. ============================================================================*/
  10. #include "cmCTestHandlerCommand.h"
  11. #include "cmCTest.h"
  12. #include "cmCTestGenericHandler.h"
  13. #include "cmMakefile.h"
  14. #include "cmSystemTools.h"
  15. #include "cmake.h"
  16. #include <sstream>
  17. #include <stdlib.h>
  18. class cmExecutionStatus;
  19. cmCTestHandlerCommand::cmCTestHandlerCommand()
  20. {
  21. const size_t INIT_SIZE = 100;
  22. size_t cc;
  23. this->Arguments.reserve(INIT_SIZE);
  24. for (cc = 0; cc < INIT_SIZE; ++cc) {
  25. this->Arguments.push_back(CM_NULLPTR);
  26. }
  27. this->Arguments[ct_RETURN_VALUE] = "RETURN_VALUE";
  28. this->Arguments[ct_SOURCE] = "SOURCE";
  29. this->Arguments[ct_BUILD] = "BUILD";
  30. this->Arguments[ct_SUBMIT_INDEX] = "SUBMIT_INDEX";
  31. this->Last = ct_LAST;
  32. this->AppendXML = false;
  33. this->Quiet = false;
  34. }
  35. bool cmCTestHandlerCommand::InitialPass(std::vector<std::string> const& args,
  36. cmExecutionStatus& /*unused*/)
  37. {
  38. // Allocate space for argument values.
  39. this->Values.clear();
  40. this->Values.resize(this->Last, CM_NULLPTR);
  41. // Process input arguments.
  42. this->ArgumentDoing = ArgumentDoingNone;
  43. for (unsigned int i = 0; i < args.size(); ++i) {
  44. // Check this argument.
  45. if (!this->CheckArgumentKeyword(args[i]) &&
  46. !this->CheckArgumentValue(args[i])) {
  47. std::ostringstream e;
  48. e << "called with unknown argument \"" << args[i] << "\".";
  49. this->SetError(e.str());
  50. return false;
  51. }
  52. // Quit if an argument is invalid.
  53. if (this->ArgumentDoing == ArgumentDoingError) {
  54. return false;
  55. }
  56. }
  57. // Set the config type of this ctest to the current value of the
  58. // CTEST_CONFIGURATION_TYPE script variable if it is defined.
  59. // The current script value trumps the -C argument on the command
  60. // line.
  61. const char* ctestConfigType =
  62. this->Makefile->GetDefinition("CTEST_CONFIGURATION_TYPE");
  63. if (ctestConfigType) {
  64. this->CTest->SetConfigType(ctestConfigType);
  65. }
  66. if (this->Values[ct_BUILD]) {
  67. this->CTest->SetCTestConfiguration(
  68. "BuildDirectory",
  69. cmSystemTools::CollapseFullPath(this->Values[ct_BUILD]).c_str(),
  70. this->Quiet);
  71. } else {
  72. const char* bdir =
  73. this->Makefile->GetSafeDefinition("CTEST_BINARY_DIRECTORY");
  74. if (bdir) {
  75. this->CTest->SetCTestConfiguration(
  76. "BuildDirectory", cmSystemTools::CollapseFullPath(bdir).c_str(),
  77. this->Quiet);
  78. } else {
  79. cmCTestLog(this->CTest, ERROR_MESSAGE, "CTEST_BINARY_DIRECTORY not set"
  80. << std::endl;);
  81. }
  82. }
  83. if (this->Values[ct_SOURCE]) {
  84. cmCTestLog(this->CTest, DEBUG, "Set source directory to: "
  85. << this->Values[ct_SOURCE] << std::endl);
  86. this->CTest->SetCTestConfiguration(
  87. "SourceDirectory",
  88. cmSystemTools::CollapseFullPath(this->Values[ct_SOURCE]).c_str(),
  89. this->Quiet);
  90. } else {
  91. this->CTest->SetCTestConfiguration(
  92. "SourceDirectory",
  93. cmSystemTools::CollapseFullPath(
  94. this->Makefile->GetSafeDefinition("CTEST_SOURCE_DIRECTORY"))
  95. .c_str(),
  96. this->Quiet);
  97. }
  98. if (const char* changeId =
  99. this->Makefile->GetDefinition("CTEST_CHANGE_ID")) {
  100. this->CTest->SetCTestConfiguration("ChangeId", changeId, this->Quiet);
  101. }
  102. cmCTestLog(this->CTest, DEBUG, "Initialize handler" << std::endl;);
  103. cmCTestGenericHandler* handler = this->InitializeHandler();
  104. if (!handler) {
  105. cmCTestLog(this->CTest, ERROR_MESSAGE, "Cannot instantiate test handler "
  106. << this->GetName() << std::endl);
  107. return false;
  108. }
  109. handler->SetAppendXML(this->AppendXML);
  110. handler->PopulateCustomVectors(this->Makefile);
  111. if (this->Values[ct_SUBMIT_INDEX]) {
  112. if (!this->CTest->GetDropSiteCDash() &&
  113. this->CTest->GetDartVersion() <= 1) {
  114. cmCTestLog(
  115. this->CTest, ERROR_MESSAGE,
  116. "Dart before version 2.0 does not support collecting submissions."
  117. << std::endl
  118. << "Please upgrade the server to Dart 2 or higher, or do not use "
  119. "SUBMIT_INDEX."
  120. << std::endl);
  121. } else {
  122. handler->SetSubmitIndex(atoi(this->Values[ct_SUBMIT_INDEX]));
  123. }
  124. }
  125. std::string current_dir = cmSystemTools::GetCurrentWorkingDirectory();
  126. cmSystemTools::ChangeDirectory(
  127. this->CTest->GetCTestConfiguration("BuildDirectory"));
  128. int res = handler->ProcessHandler();
  129. if (this->Values[ct_RETURN_VALUE] && *this->Values[ct_RETURN_VALUE]) {
  130. std::ostringstream str;
  131. str << res;
  132. this->Makefile->AddDefinition(this->Values[ct_RETURN_VALUE],
  133. str.str().c_str());
  134. }
  135. cmSystemTools::ChangeDirectory(current_dir);
  136. return true;
  137. }
  138. bool cmCTestHandlerCommand::CheckArgumentKeyword(std::string const& arg)
  139. {
  140. // Look for non-value arguments common to all commands.
  141. if (arg == "APPEND") {
  142. this->ArgumentDoing = ArgumentDoingNone;
  143. this->AppendXML = true;
  144. return true;
  145. }
  146. if (arg == "QUIET") {
  147. this->ArgumentDoing = ArgumentDoingNone;
  148. this->Quiet = true;
  149. return true;
  150. }
  151. // Check for a keyword in our argument/value table.
  152. for (unsigned int k = 0; k < this->Arguments.size(); ++k) {
  153. if (this->Arguments[k] && arg == this->Arguments[k]) {
  154. this->ArgumentDoing = ArgumentDoingKeyword;
  155. this->ArgumentIndex = k;
  156. return true;
  157. }
  158. }
  159. return false;
  160. }
  161. bool cmCTestHandlerCommand::CheckArgumentValue(std::string const& arg)
  162. {
  163. if (this->ArgumentDoing == ArgumentDoingKeyword) {
  164. this->ArgumentDoing = ArgumentDoingNone;
  165. unsigned int k = this->ArgumentIndex;
  166. if (this->Values[k]) {
  167. std::ostringstream e;
  168. e << "Called with more than one value for " << this->Arguments[k];
  169. this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
  170. this->ArgumentDoing = ArgumentDoingError;
  171. return true;
  172. }
  173. this->Values[k] = arg.c_str();
  174. cmCTestLog(this->CTest, DEBUG, "Set " << this->Arguments[k] << " to "
  175. << arg << "\n");
  176. return true;
  177. }
  178. return false;
  179. }