cmCTestSubmitHandler.cxx 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260
  1. /*=========================================================================
  2. Program: CMake - Cross-Platform Makefile Generator
  3. Module: $RCSfile$
  4. Language: C++
  5. Date: $Date$
  6. Version: $Revision$
  7. Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
  8. See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
  9. This software is distributed WITHOUT ANY WARRANTY; without even
  10. the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  11. PURPOSE. See the above copyright notices for more information.
  12. =========================================================================*/
  13. #include "cmCTestSubmitHandler.h"
  14. #include "cmSystemTools.h"
  15. #include "cmVersion.h"
  16. #include "cmGeneratedFileStream.h"
  17. #include "cmCTest.h"
  18. #include <cmsys/Process.h>
  19. #include <cmsys/Base64.h>
  20. // For XML-RPC submission
  21. #include "cm_xmlrpc.h"
  22. // For curl submission
  23. #include "cm_curl.h"
  24. #include <sys/stat.h>
  25. typedef std::vector<char> cmCTestSubmitHandlerVectorOfChar;
  26. static size_t
  27. cmCTestSubmitHandlerWriteMemoryCallback(void *ptr, size_t size, size_t nmemb,
  28. void *data)
  29. {
  30. register int realsize = (int)(size * nmemb);
  31. cmCTestSubmitHandlerVectorOfChar *vec
  32. = static_cast<cmCTestSubmitHandlerVectorOfChar*>(data);
  33. const char* chPtr = static_cast<char*>(ptr);
  34. vec->insert(vec->end(), chPtr, chPtr + realsize);
  35. return realsize;
  36. }
  37. static size_t
  38. cmCTestSubmitHandlerCurlDebugCallback(CURL *, curl_infotype, char *chPtr,
  39. size_t size, void *data)
  40. {
  41. cmCTestSubmitHandlerVectorOfChar *vec
  42. = static_cast<cmCTestSubmitHandlerVectorOfChar*>(data);
  43. vec->insert(vec->end(), chPtr, chPtr + size);
  44. return size;
  45. }
  46. //----------------------------------------------------------------------------
  47. cmCTestSubmitHandler::cmCTestSubmitHandler() : HTTPProxy(), FTPProxy()
  48. {
  49. this->Initialize();
  50. }
  51. //----------------------------------------------------------------------------
  52. void cmCTestSubmitHandler::Initialize()
  53. {
  54. // We submit all available parts by default.
  55. for(cmCTest::Part p = cmCTest::PartStart;
  56. p != cmCTest::PartCount; p = cmCTest::Part(p+1))
  57. {
  58. this->SubmitPart[p] = true;
  59. }
  60. this->CDash = false;
  61. this->Superclass::Initialize();
  62. this->HTTPProxy = "";
  63. this->HTTPProxyType = 0;
  64. this->HTTPProxyAuth = "";
  65. this->FTPProxy = "";
  66. this->FTPProxyType = 0;
  67. this->LogFile = 0;
  68. this->Files.clear();
  69. }
  70. //----------------------------------------------------------------------------
  71. bool cmCTestSubmitHandler::SubmitUsingFTP(const cmStdString& localprefix,
  72. const std::set<cmStdString>& files,
  73. const cmStdString& remoteprefix,
  74. const cmStdString& url)
  75. {
  76. CURL *curl;
  77. CURLcode res;
  78. FILE* ftpfile;
  79. char error_buffer[1024];
  80. /* In windows, this will init the winsock stuff */
  81. ::curl_global_init(CURL_GLOBAL_ALL);
  82. cmCTest::SetOfStrings::const_iterator file;
  83. for ( file = files.begin(); file != files.end(); ++file )
  84. {
  85. /* get a curl handle */
  86. curl = curl_easy_init();
  87. if(curl)
  88. {
  89. // Using proxy
  90. if ( this->FTPProxyType > 0 )
  91. {
  92. curl_easy_setopt(curl, CURLOPT_PROXY, this->FTPProxy.c_str());
  93. switch (this->FTPProxyType)
  94. {
  95. case 2:
  96. curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS4);
  97. break;
  98. case 3:
  99. curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
  100. break;
  101. default:
  102. curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
  103. }
  104. }
  105. // enable uploading
  106. ::curl_easy_setopt(curl, CURLOPT_UPLOAD, 1) ;
  107. cmStdString local_file = *file;
  108. if ( !cmSystemTools::FileExists(local_file.c_str()) )
  109. {
  110. local_file = localprefix + "/" + *file;
  111. }
  112. cmStdString upload_as
  113. = url + "/" + remoteprefix + cmSystemTools::GetFilenameName(*file);
  114. struct stat st;
  115. if ( ::stat(local_file.c_str(), &st) )
  116. {
  117. cmCTestLog(this->CTest, ERROR_MESSAGE, " Cannot find file: "
  118. << local_file.c_str() << std::endl);
  119. ::curl_easy_cleanup(curl);
  120. ::curl_global_cleanup();
  121. return false;
  122. }
  123. ftpfile = ::fopen(local_file.c_str(), "rb");
  124. *this->LogFile << "\tUpload file: " << local_file.c_str() << " to "
  125. << upload_as.c_str() << std::endl;
  126. cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " Upload file: "
  127. << local_file.c_str() << " to "
  128. << upload_as.c_str() << std::endl);
  129. ::curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
  130. // specify target
  131. ::curl_easy_setopt(curl,CURLOPT_URL, upload_as.c_str());
  132. // now specify which file to upload
  133. ::curl_easy_setopt(curl, CURLOPT_INFILE, ftpfile);
  134. // and give the size of the upload (optional)
  135. ::curl_easy_setopt(curl, CURLOPT_INFILESIZE,
  136. static_cast<long>(st.st_size));
  137. // and give curl the buffer for errors
  138. ::curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, &error_buffer);
  139. // specify handler for output
  140. ::curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,
  141. cmCTestSubmitHandlerWriteMemoryCallback);
  142. ::curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION,
  143. cmCTestSubmitHandlerCurlDebugCallback);
  144. /* we pass our 'chunk' struct to the callback function */
  145. cmCTestSubmitHandlerVectorOfChar chunk;
  146. cmCTestSubmitHandlerVectorOfChar chunkDebug;
  147. ::curl_easy_setopt(curl, CURLOPT_FILE, (void *)&chunk);
  148. ::curl_easy_setopt(curl, CURLOPT_DEBUGDATA, (void *)&chunkDebug);
  149. // Now run off and do what you've been told!
  150. res = ::curl_easy_perform(curl);
  151. if ( chunk.size() > 0 )
  152. {
  153. cmCTestLog(this->CTest, DEBUG, "CURL output: ["
  154. << cmCTestLogWrite(&*chunk.begin(), chunk.size()) << "]"
  155. << std::endl);
  156. }
  157. if ( chunkDebug.size() > 0 )
  158. {
  159. cmCTestLog(this->CTest, DEBUG, "CURL debug output: ["
  160. << cmCTestLogWrite(&*chunkDebug.begin(), chunkDebug.size()) << "]"
  161. << std::endl);
  162. }
  163. fclose(ftpfile);
  164. if ( res )
  165. {
  166. cmCTestLog(this->CTest, ERROR_MESSAGE,
  167. " Error when uploading file: "
  168. << local_file.c_str() << std::endl);
  169. cmCTestLog(this->CTest, ERROR_MESSAGE, " Error message was: "
  170. << error_buffer << std::endl);
  171. *this->LogFile << " Error when uploading file: "
  172. << local_file.c_str()
  173. << std::endl
  174. << " Error message was: "
  175. << error_buffer << std::endl
  176. << " Curl output was: ";
  177. // avoid dereference of empty vector
  178. if(chunk.size())
  179. {
  180. *this->LogFile << cmCTestLogWrite(&*chunk.begin(), chunk.size());
  181. cmCTestLog(this->CTest, ERROR_MESSAGE, "CURL output: ["
  182. << cmCTestLogWrite(&*chunk.begin(), chunk.size()) << "]"
  183. << std::endl);
  184. }
  185. *this->LogFile << std::endl;
  186. ::curl_easy_cleanup(curl);
  187. ::curl_global_cleanup();
  188. return false;
  189. }
  190. // always cleanup
  191. ::curl_easy_cleanup(curl);
  192. cmCTestLog(this->CTest, HANDLER_OUTPUT, " Uploaded: " + local_file
  193. << std::endl);
  194. }
  195. }
  196. ::curl_global_cleanup();
  197. return true;
  198. }
  199. //----------------------------------------------------------------------------
  200. // Uploading files is simpler
  201. bool cmCTestSubmitHandler::SubmitUsingHTTP(const cmStdString& localprefix,
  202. const std::set<cmStdString>& files,
  203. const cmStdString& remoteprefix,
  204. const cmStdString& url)
  205. {
  206. CURL *curl;
  207. CURLcode res;
  208. FILE* ftpfile;
  209. char error_buffer[1024];
  210. /* In windows, this will init the winsock stuff */
  211. ::curl_global_init(CURL_GLOBAL_ALL);
  212. cmStdString dropMethod(this->CTest->GetCTestConfiguration("DropMethod"));
  213. cmStdString curlopt(this->CTest->GetCTestConfiguration("CurlOptions"));
  214. std::vector<std::string> args;
  215. cmSystemTools::ExpandListArgument(curlopt.c_str(), args);
  216. bool verifyPeerOff = false;
  217. bool verifyHostOff = false;
  218. for( std::vector<std::string>::iterator i = args.begin();
  219. i != args.end(); ++i)
  220. {
  221. if(*i == "CURLOPT_SSL_VERIFYPEER_OFF")
  222. {
  223. verifyPeerOff = true;
  224. }
  225. if(*i == "CURLOPT_SSL_VERIFYHOST_OFF")
  226. {
  227. verifyHostOff = true;
  228. }
  229. }
  230. cmStdString::size_type kk;
  231. cmCTest::SetOfStrings::const_iterator file;
  232. for ( file = files.begin(); file != files.end(); ++file )
  233. {
  234. /* get a curl handle */
  235. curl = curl_easy_init();
  236. if(curl)
  237. {
  238. if(verifyPeerOff)
  239. {
  240. cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
  241. " Set CURLOPT_SSL_VERIFYPEER to off\n");
  242. curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
  243. }
  244. if(verifyHostOff)
  245. {
  246. cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
  247. " Set CURLOPT_SSL_VERIFYHOST to off\n");
  248. curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
  249. }
  250. // Using proxy
  251. if ( this->HTTPProxyType > 0 )
  252. {
  253. curl_easy_setopt(curl, CURLOPT_PROXY, this->HTTPProxy.c_str());
  254. switch (this->HTTPProxyType)
  255. {
  256. case 2:
  257. curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS4);
  258. break;
  259. case 3:
  260. curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
  261. break;
  262. default:
  263. curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
  264. if (this->HTTPProxyAuth.size() > 0)
  265. {
  266. curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD,
  267. this->HTTPProxyAuth.c_str());
  268. }
  269. }
  270. }
  271. /* enable uploading */
  272. curl_easy_setopt(curl, CURLOPT_UPLOAD, 1) ;
  273. /* HTTP PUT please */
  274. ::curl_easy_setopt(curl, CURLOPT_PUT, 1);
  275. ::curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
  276. cmStdString local_file = *file;
  277. if ( !cmSystemTools::FileExists(local_file.c_str()) )
  278. {
  279. local_file = localprefix + "/" + *file;
  280. }
  281. cmStdString remote_file
  282. = remoteprefix + cmSystemTools::GetFilenameName(*file);
  283. *this->LogFile << "\tUpload file: " << local_file.c_str() << " to "
  284. << remote_file.c_str() << std::endl;
  285. cmStdString ofile = "";
  286. for ( kk = 0; kk < remote_file.size(); kk ++ )
  287. {
  288. char c = remote_file[kk];
  289. char hexCh[4] = { 0, 0, 0, 0 };
  290. hexCh[0] = c;
  291. switch ( c )
  292. {
  293. case '+':
  294. case '?':
  295. case '/':
  296. case '\\':
  297. case '&':
  298. case ' ':
  299. case '=':
  300. case '%':
  301. sprintf(hexCh, "%%%02X", (int)c);
  302. ofile.append(hexCh);
  303. break;
  304. default:
  305. ofile.append(hexCh);
  306. }
  307. }
  308. cmStdString upload_as
  309. = url + ((url.find("?",0) == cmStdString::npos) ? "?" : "&")
  310. + "FileName=" + ofile;
  311. struct stat st;
  312. if ( ::stat(local_file.c_str(), &st) )
  313. {
  314. cmCTestLog(this->CTest, ERROR_MESSAGE, " Cannot find file: "
  315. << local_file.c_str() << std::endl);
  316. ::curl_easy_cleanup(curl);
  317. ::curl_global_cleanup();
  318. return false;
  319. }
  320. ftpfile = ::fopen(local_file.c_str(), "rb");
  321. cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " Upload file: "
  322. << local_file.c_str() << " to "
  323. << upload_as.c_str() << " Size: " << st.st_size << std::endl);
  324. // specify target
  325. ::curl_easy_setopt(curl,CURLOPT_URL, upload_as.c_str());
  326. // now specify which file to upload
  327. ::curl_easy_setopt(curl, CURLOPT_INFILE, ftpfile);
  328. // and give the size of the upload (optional)
  329. ::curl_easy_setopt(curl, CURLOPT_INFILESIZE,
  330. static_cast<long>(st.st_size));
  331. // and give curl the buffer for errors
  332. ::curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, &error_buffer);
  333. // specify handler for output
  334. ::curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,
  335. cmCTestSubmitHandlerWriteMemoryCallback);
  336. ::curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION,
  337. cmCTestSubmitHandlerCurlDebugCallback);
  338. /* we pass our 'chunk' struct to the callback function */
  339. cmCTestSubmitHandlerVectorOfChar chunk;
  340. cmCTestSubmitHandlerVectorOfChar chunkDebug;
  341. ::curl_easy_setopt(curl, CURLOPT_FILE, (void *)&chunk);
  342. ::curl_easy_setopt(curl, CURLOPT_DEBUGDATA, (void *)&chunkDebug);
  343. // Now run off and do what you've been told!
  344. res = ::curl_easy_perform(curl);
  345. if ( chunk.size() > 0 )
  346. {
  347. cmCTestLog(this->CTest, DEBUG, "CURL output: ["
  348. << cmCTestLogWrite(&*chunk.begin(), chunk.size()) << "]"
  349. << std::endl);
  350. }
  351. if ( chunkDebug.size() > 0 )
  352. {
  353. cmCTestLog(this->CTest, DEBUG, "CURL debug output: ["
  354. << cmCTestLogWrite(&*chunkDebug.begin(), chunkDebug.size()) << "]"
  355. << std::endl);
  356. }
  357. fclose(ftpfile);
  358. if ( res )
  359. {
  360. cmCTestLog(this->CTest, ERROR_MESSAGE,
  361. " Error when uploading file: "
  362. << local_file.c_str() << std::endl);
  363. cmCTestLog(this->CTest, ERROR_MESSAGE, " Error message was: "
  364. << error_buffer << std::endl);
  365. *this->LogFile << " Error when uploading file: "
  366. << local_file.c_str()
  367. << std::endl
  368. << " Error message was: " << error_buffer
  369. << std::endl;
  370. // avoid deref of begin for zero size array
  371. if(chunk.size())
  372. {
  373. *this->LogFile << " Curl output was: "
  374. << cmCTestLogWrite(&*chunk.begin(), chunk.size())
  375. << std::endl;
  376. cmCTestLog(this->CTest, ERROR_MESSAGE, "CURL output: ["
  377. << cmCTestLogWrite(&*chunk.begin(), chunk.size()) << "]"
  378. << std::endl);
  379. }
  380. ::curl_easy_cleanup(curl);
  381. ::curl_global_cleanup();
  382. return false;
  383. }
  384. // always cleanup
  385. ::curl_easy_cleanup(curl);
  386. cmCTestLog(this->CTest, HANDLER_OUTPUT, " Uploaded: " + local_file
  387. << std::endl);
  388. }
  389. }
  390. ::curl_global_cleanup();
  391. return true;
  392. }
  393. //----------------------------------------------------------------------------
  394. bool cmCTestSubmitHandler::TriggerUsingHTTP(
  395. const std::set<cmStdString>& files,
  396. const cmStdString& remoteprefix,
  397. const cmStdString& url)
  398. {
  399. CURL *curl;
  400. char error_buffer[1024];
  401. /* In windows, this will init the winsock stuff */
  402. ::curl_global_init(CURL_GLOBAL_ALL);
  403. cmCTest::SetOfStrings::const_iterator file;
  404. for ( file = files.begin(); file != files.end(); ++file )
  405. {
  406. /* get a curl handle */
  407. curl = curl_easy_init();
  408. if(curl)
  409. {
  410. // Using proxy
  411. if ( this->HTTPProxyType > 0 )
  412. {
  413. curl_easy_setopt(curl, CURLOPT_PROXY, this->HTTPProxy.c_str());
  414. switch (this->HTTPProxyType)
  415. {
  416. case 2:
  417. curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS4);
  418. break;
  419. case 3:
  420. curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
  421. break;
  422. default:
  423. curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
  424. if (this->HTTPProxyAuth.size() > 0)
  425. {
  426. curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD,
  427. this->HTTPProxyAuth.c_str());
  428. }
  429. }
  430. }
  431. ::curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
  432. // and give curl the buffer for errors
  433. ::curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, &error_buffer);
  434. // specify handler for output
  435. ::curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,
  436. cmCTestSubmitHandlerWriteMemoryCallback);
  437. ::curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION,
  438. cmCTestSubmitHandlerCurlDebugCallback);
  439. /* we pass our 'chunk' struct to the callback function */
  440. cmCTestSubmitHandlerVectorOfChar chunk;
  441. cmCTestSubmitHandlerVectorOfChar chunkDebug;
  442. ::curl_easy_setopt(curl, CURLOPT_FILE, (void *)&chunk);
  443. ::curl_easy_setopt(curl, CURLOPT_DEBUGDATA, (void *)&chunkDebug);
  444. cmStdString rfile
  445. = remoteprefix + cmSystemTools::GetFilenameName(*file);
  446. cmStdString ofile = "";
  447. cmStdString::iterator kk;
  448. for ( kk = rfile.begin(); kk < rfile.end(); ++ kk)
  449. {
  450. char c = *kk;
  451. char hexCh[4] = { 0, 0, 0, 0 };
  452. hexCh[0] = c;
  453. switch ( c )
  454. {
  455. case '+':
  456. case '?':
  457. case '/':
  458. case '\\':
  459. case '&':
  460. case ' ':
  461. case '=':
  462. case '%':
  463. sprintf(hexCh, "%%%02X", (int)c);
  464. ofile.append(hexCh);
  465. break;
  466. default:
  467. ofile.append(hexCh);
  468. }
  469. }
  470. cmStdString turl
  471. = url + ((url.find("?",0) == cmStdString::npos) ? "?" : "&")
  472. + "xmlfile=" + ofile;
  473. *this->LogFile << "Trigger url: " << turl.c_str() << std::endl;
  474. cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " Trigger url: "
  475. << turl.c_str() << std::endl);
  476. curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
  477. curl_easy_setopt(curl, CURLOPT_URL, turl.c_str());
  478. if ( curl_easy_perform(curl) )
  479. {
  480. cmCTestLog(this->CTest, ERROR_MESSAGE, " Error when triggering: "
  481. << turl.c_str() << std::endl);
  482. cmCTestLog(this->CTest, ERROR_MESSAGE, " Error message was: "
  483. << error_buffer << std::endl);
  484. *this->LogFile << "\tTrigerring failed with error: " << error_buffer
  485. << std::endl
  486. << " Error message was: " << error_buffer
  487. << std::endl;
  488. if(chunk.size())
  489. {
  490. *this->LogFile
  491. << " Curl output was: "
  492. << cmCTestLogWrite(&*chunk.begin(), chunk.size()) << std::endl;
  493. cmCTestLog(this->CTest, ERROR_MESSAGE, "CURL output: ["
  494. << cmCTestLogWrite(&*chunk.begin(), chunk.size()) << "]"
  495. << std::endl);
  496. }
  497. ::curl_easy_cleanup(curl);
  498. ::curl_global_cleanup();
  499. return false;
  500. }
  501. if ( chunk.size() > 0 )
  502. {
  503. cmCTestLog(this->CTest, DEBUG, "CURL output: ["
  504. << cmCTestLogWrite(&*chunk.begin(), chunk.size()) << "]"
  505. << std::endl);
  506. }
  507. if ( chunkDebug.size() > 0 )
  508. {
  509. cmCTestLog(this->CTest, DEBUG, "CURL debug output: ["
  510. << cmCTestLogWrite(&*chunkDebug.begin(), chunkDebug.size())
  511. << "]" << std::endl);
  512. }
  513. // always cleanup
  514. ::curl_easy_cleanup(curl);
  515. cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, std::endl);
  516. }
  517. }
  518. ::curl_global_cleanup();
  519. cmCTestLog(this->CTest, HANDLER_OUTPUT, " Dart server triggered..."
  520. << std::endl);
  521. return true;
  522. }
  523. //----------------------------------------------------------------------------
  524. bool cmCTestSubmitHandler::SubmitUsingSCP(
  525. const cmStdString& scp_command,
  526. const cmStdString& localprefix,
  527. const std::set<cmStdString>& files,
  528. const cmStdString& remoteprefix,
  529. const cmStdString& url)
  530. {
  531. if ( !scp_command.size() || !localprefix.size() ||
  532. !files.size() || !remoteprefix.size() || !url.size() )
  533. {
  534. return 0;
  535. }
  536. std::vector<const char*> argv;
  537. argv.push_back(scp_command.c_str()); // Scp command
  538. argv.push_back(scp_command.c_str()); // Dummy string for file
  539. argv.push_back(scp_command.c_str()); // Dummy string for remote url
  540. argv.push_back(0);
  541. cmsysProcess* cp = cmsysProcess_New();
  542. cmsysProcess_SetOption(cp, cmsysProcess_Option_HideWindow, 1);
  543. //cmsysProcess_SetTimeout(cp, timeout);
  544. int problems = 0;
  545. cmCTest::SetOfStrings::const_iterator file;
  546. for ( file = files.begin(); file != files.end(); ++file )
  547. {
  548. int retVal;
  549. std::string lfname = localprefix;
  550. cmSystemTools::ConvertToUnixSlashes(lfname);
  551. lfname += "/" + *file;
  552. lfname = cmSystemTools::ConvertToOutputPath(lfname.c_str());
  553. argv[1] = lfname.c_str();
  554. std::string rfname = url + "/" + remoteprefix + *file;
  555. argv[2] = rfname.c_str();
  556. cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "Execute \"" << argv[0]
  557. << "\" \"" << argv[1] << "\" \""
  558. << argv[2] << "\"" << std::endl);
  559. *this->LogFile << "Execute \"" << argv[0] << "\" \"" << argv[1] << "\" \""
  560. << argv[2] << "\"" << std::endl;
  561. cmsysProcess_SetCommand(cp, &*argv.begin());
  562. cmsysProcess_Execute(cp);
  563. char* data;
  564. int length;
  565. while(cmsysProcess_WaitForData(cp, &data, &length, 0))
  566. {
  567. cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
  568. cmCTestLogWrite(data, length));
  569. }
  570. cmsysProcess_WaitForExit(cp, 0);
  571. int result = cmsysProcess_GetState(cp);
  572. if(result == cmsysProcess_State_Exited)
  573. {
  574. retVal = cmsysProcess_GetExitValue(cp);
  575. if ( retVal != 0 )
  576. {
  577. cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, "\tSCP returned: "
  578. << retVal << std::endl);
  579. *this->LogFile << "\tSCP returned: " << retVal << std::endl;
  580. problems ++;
  581. }
  582. }
  583. else if(result == cmsysProcess_State_Exception)
  584. {
  585. retVal = cmsysProcess_GetExitException(cp);
  586. cmCTestLog(this->CTest, ERROR_MESSAGE, "\tThere was an exception: "
  587. << retVal << std::endl);
  588. *this->LogFile << "\tThere was an exception: " << retVal << std::endl;
  589. problems ++;
  590. }
  591. else if(result == cmsysProcess_State_Expired)
  592. {
  593. cmCTestLog(this->CTest, ERROR_MESSAGE, "\tThere was a timeout"
  594. << std::endl);
  595. *this->LogFile << "\tThere was a timeout" << std::endl;
  596. problems ++;
  597. }
  598. else if(result == cmsysProcess_State_Error)
  599. {
  600. cmCTestLog(this->CTest, ERROR_MESSAGE, "\tError executing SCP: "
  601. << cmsysProcess_GetErrorString(cp) << std::endl);
  602. *this->LogFile << "\tError executing SCP: "
  603. << cmsysProcess_GetErrorString(cp) << std::endl;
  604. problems ++;
  605. }
  606. }
  607. cmsysProcess_Delete(cp);
  608. if ( problems )
  609. {
  610. return false;
  611. }
  612. return true;
  613. }
  614. //----------------------------------------------------------------------------
  615. bool cmCTestSubmitHandler::SubmitUsingCP(
  616. const cmStdString& localprefix,
  617. const std::set<cmStdString>& files,
  618. const cmStdString& remoteprefix,
  619. const cmStdString& destination)
  620. {
  621. if ( !localprefix.size() ||
  622. !files.size() || !remoteprefix.size() || !destination.size() )
  623. {
  624. cmCTestLog(this->CTest, ERROR_MESSAGE,
  625. "Missing arguments for submit via cp:\n"
  626. << "\tlocalprefix: " << localprefix << "\n"
  627. << "\tNumber of files: " << files.size() << "\n"
  628. << "\tremoteprefix: " << remoteprefix << "\n"
  629. << "\tdestination: " << destination << std::endl);
  630. return 0;
  631. }
  632. cmCTest::SetOfStrings::const_iterator file;
  633. bool problems = false;
  634. for ( file = files.begin(); file != files.end(); ++file )
  635. {
  636. std::string lfname = localprefix;
  637. cmSystemTools::ConvertToUnixSlashes(lfname);
  638. lfname += "/" + *file;
  639. std::string rfname = destination + "/" + remoteprefix + *file;
  640. cmSystemTools::CopyFileAlways(lfname.c_str(), rfname.c_str());
  641. cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " Copy file: "
  642. << lfname.c_str() << " to "
  643. << rfname.c_str() << std::endl);
  644. }
  645. std::string tagDoneFile = destination + "/" + remoteprefix + "DONE";
  646. cmSystemTools::Touch(tagDoneFile.c_str(), true);
  647. if ( problems )
  648. {
  649. return false;
  650. }
  651. return true;
  652. }
  653. //----------------------------------------------------------------------------
  654. bool cmCTestSubmitHandler::SubmitUsingXMLRPC(const cmStdString& localprefix,
  655. const std::set<cmStdString>& files,
  656. const cmStdString& remoteprefix,
  657. const cmStdString& url)
  658. {
  659. xmlrpc_env env;
  660. char ctestString[] = "CTest";
  661. std::string ctestVersionString = cmVersion::GetCMakeVersion();
  662. char* ctestVersion = const_cast<char*>(ctestVersionString.c_str());
  663. cmStdString realURL = url + "/" + remoteprefix + "/Command/";
  664. /* Start up our XML-RPC client library. */
  665. xmlrpc_client_init(XMLRPC_CLIENT_NO_FLAGS, ctestString, ctestVersion);
  666. /* Initialize our error-handling environment. */
  667. xmlrpc_env_init(&env);
  668. /* Call the famous server at UserLand. */
  669. cmCTestLog(this->CTest, HANDLER_OUTPUT, " Submitting to: "
  670. << realURL.c_str() << " (" << remoteprefix.c_str() << ")" << std::endl);
  671. cmCTest::SetOfStrings::const_iterator file;
  672. for ( file = files.begin(); file != files.end(); ++file )
  673. {
  674. xmlrpc_value *result;
  675. cmStdString local_file = *file;
  676. if ( !cmSystemTools::FileExists(local_file.c_str()) )
  677. {
  678. local_file = localprefix + "/" + *file;
  679. }
  680. cmCTestLog(this->CTest, HANDLER_OUTPUT, " Submit file: "
  681. << local_file.c_str() << std::endl);
  682. struct stat st;
  683. if ( ::stat(local_file.c_str(), &st) )
  684. {
  685. cmCTestLog(this->CTest, ERROR_MESSAGE, " Cannot find file: "
  686. << local_file.c_str() << std::endl);
  687. return false;
  688. }
  689. // off_t can be bigger than size_t. fread takes size_t.
  690. // make sure the file is not too big.
  691. if(static_cast<off_t>(static_cast<size_t>(st.st_size)) !=
  692. static_cast<off_t>(st.st_size))
  693. {
  694. cmCTestLog(this->CTest, ERROR_MESSAGE, " File too big: "
  695. << local_file.c_str() << std::endl);
  696. return false;
  697. }
  698. size_t fileSize = static_cast<size_t>(st.st_size);
  699. FILE* fp = fopen(local_file.c_str(), "rb");
  700. if ( !fp )
  701. {
  702. cmCTestLog(this->CTest, ERROR_MESSAGE, " Cannot open file: "
  703. << local_file.c_str() << std::endl);
  704. return false;
  705. }
  706. unsigned char *fileBuffer = new unsigned char[fileSize];
  707. if ( fread(fileBuffer, 1, fileSize, fp) != fileSize )
  708. {
  709. delete [] fileBuffer;
  710. fclose(fp);
  711. cmCTestLog(this->CTest, ERROR_MESSAGE, " Cannot read file: "
  712. << local_file.c_str() << std::endl);
  713. return false;
  714. }
  715. fclose(fp);
  716. char remoteCommand[] = "Submit.put";
  717. char* pRealURL = const_cast<char*>(realURL.c_str());
  718. result = xmlrpc_client_call(&env, pRealURL, remoteCommand,
  719. "(6)", fileBuffer, (xmlrpc_int32)fileSize );
  720. delete [] fileBuffer;
  721. if ( env.fault_occurred )
  722. {
  723. cmCTestLog(this->CTest, ERROR_MESSAGE, " Submission problem: "
  724. << env.fault_string << " (" << env.fault_code << ")" << std::endl);
  725. xmlrpc_env_clean(&env);
  726. xmlrpc_client_cleanup();
  727. return false;
  728. }
  729. /* Dispose of our result value. */
  730. xmlrpc_DECREF(result);
  731. }
  732. /* Clean up our error-handling environment. */
  733. xmlrpc_env_clean(&env);
  734. /* Shutdown our XML-RPC client library. */
  735. xmlrpc_client_cleanup();
  736. return true;
  737. }
  738. //----------------------------------------------------------------------------
  739. int cmCTestSubmitHandler::ProcessHandler()
  740. {
  741. std::string iscdash = this->CTest->GetCTestConfiguration("IsCDash");
  742. // cdash does not need to trigger so just return true
  743. if(iscdash.size())
  744. {
  745. this->CDash = true;
  746. }
  747. const std::string &buildDirectory
  748. = this->CTest->GetCTestConfiguration("BuildDirectory");
  749. if ( buildDirectory.size() == 0 )
  750. {
  751. cmCTestLog(this->CTest, ERROR_MESSAGE,
  752. "Cannot find BuildDirectory key in the DartConfiguration.tcl"
  753. << std::endl);
  754. return -1;
  755. }
  756. if ( getenv("HTTP_PROXY") )
  757. {
  758. this->HTTPProxyType = 1;
  759. this->HTTPProxy = getenv("HTTP_PROXY");
  760. if ( getenv("HTTP_PROXY_PORT") )
  761. {
  762. this->HTTPProxy += ":";
  763. this->HTTPProxy += getenv("HTTP_PROXY_PORT");
  764. }
  765. if ( getenv("HTTP_PROXY_TYPE") )
  766. {
  767. cmStdString type = getenv("HTTP_PROXY_TYPE");
  768. // HTTP/SOCKS4/SOCKS5
  769. if ( type == "HTTP" )
  770. {
  771. this->HTTPProxyType = 1;
  772. }
  773. else if ( type == "SOCKS4" )
  774. {
  775. this->HTTPProxyType = 2;
  776. }
  777. else if ( type == "SOCKS5" )
  778. {
  779. this->HTTPProxyType = 3;
  780. }
  781. }
  782. if ( getenv("HTTP_PROXY_USER") )
  783. {
  784. this->HTTPProxyAuth = getenv("HTTP_PROXY_USER");
  785. }
  786. if ( getenv("HTTP_PROXY_PASSWD") )
  787. {
  788. this->HTTPProxyAuth += ":";
  789. this->HTTPProxyAuth += getenv("HTTP_PROXY_PASSWD");
  790. }
  791. }
  792. if ( getenv("FTP_PROXY") )
  793. {
  794. this->FTPProxyType = 1;
  795. this->FTPProxy = getenv("FTP_PROXY");
  796. if ( getenv("FTP_PROXY_PORT") )
  797. {
  798. this->FTPProxy += ":";
  799. this->FTPProxy += getenv("FTP_PROXY_PORT");
  800. }
  801. if ( getenv("FTP_PROXY_TYPE") )
  802. {
  803. cmStdString type = getenv("FTP_PROXY_TYPE");
  804. // HTTP/SOCKS4/SOCKS5
  805. if ( type == "HTTP" )
  806. {
  807. this->FTPProxyType = 1;
  808. }
  809. else if ( type == "SOCKS4" )
  810. {
  811. this->FTPProxyType = 2;
  812. }
  813. else if ( type == "SOCKS5" )
  814. {
  815. this->FTPProxyType = 3;
  816. }
  817. }
  818. }
  819. if ( this->HTTPProxy.size() > 0 )
  820. {
  821. cmCTestLog(this->CTest, HANDLER_OUTPUT, " Use HTTP Proxy: "
  822. << this->HTTPProxy << std::endl);
  823. }
  824. if ( this->FTPProxy.size() > 0 )
  825. {
  826. cmCTestLog(this->CTest, HANDLER_OUTPUT, " Use FTP Proxy: "
  827. << this->FTPProxy << std::endl);
  828. }
  829. cmGeneratedFileStream ofs;
  830. this->StartLogFile("Submit", ofs);
  831. cmCTest::SetOfStrings files;
  832. std::string prefix = this->GetSubmitResultsPrefix();
  833. if (!this->Files.empty())
  834. {
  835. // Submit the explicitly selected files:
  836. //
  837. cmCTest::SetOfStrings::const_iterator it;
  838. for (it = this->Files.begin(); it != this->Files.end(); ++it)
  839. {
  840. files.insert(*it);
  841. }
  842. }
  843. // Add to the list of files to submit from any selected, existing parts:
  844. //
  845. // TODO:
  846. // Check if test is enabled
  847. this->CTest->AddIfExists(cmCTest::PartUpdate, "Update.xml");
  848. this->CTest->AddIfExists(cmCTest::PartConfigure, "Configure.xml");
  849. this->CTest->AddIfExists(cmCTest::PartBuild, "Build.xml");
  850. this->CTest->AddIfExists(cmCTest::PartTest, "Test.xml");
  851. if(this->CTest->AddIfExists(cmCTest::PartCoverage, "Coverage.xml"))
  852. {
  853. cmCTest::VectorOfStrings gfiles;
  854. std::string gpath
  855. = buildDirectory + "/Testing/" + this->CTest->GetCurrentTag();
  856. std::string::size_type glen = gpath.size() + 1;
  857. gpath = gpath + "/CoverageLog*";
  858. cmCTestLog(this->CTest, DEBUG, "Globbing for: " << gpath.c_str()
  859. << std::endl);
  860. if ( cmSystemTools::SimpleGlob(gpath, gfiles, 1) )
  861. {
  862. size_t cc;
  863. for ( cc = 0; cc < gfiles.size(); cc ++ )
  864. {
  865. gfiles[cc] = gfiles[cc].substr(glen);
  866. cmCTestLog(this->CTest, DEBUG, "Glob file: " << gfiles[cc].c_str()
  867. << std::endl);
  868. this->CTest->AddSubmitFile(cmCTest::PartCoverage, gfiles[cc].c_str());
  869. }
  870. }
  871. else
  872. {
  873. cmCTestLog(this->CTest, ERROR_MESSAGE, "Problem globbing" << std::endl);
  874. }
  875. }
  876. this->CTest->AddIfExists(cmCTest::PartMemCheck, "DynamicAnalysis.xml");
  877. this->CTest->AddIfExists(cmCTest::PartMemCheck, "Purify.xml");
  878. this->CTest->AddIfExists(cmCTest::PartNotes, "Notes.xml");
  879. // Query parts for files to submit.
  880. for(cmCTest::Part p = cmCTest::PartStart;
  881. p != cmCTest::PartCount; p = cmCTest::Part(p+1))
  882. {
  883. // Skip parts we are not submitting.
  884. if(!this->SubmitPart[p])
  885. {
  886. continue;
  887. }
  888. // Submit files from this part.
  889. std::vector<std::string> const& pfiles = this->CTest->GetSubmitFiles(p);
  890. for(std::vector<std::string>::const_iterator pi = pfiles.begin();
  891. pi != pfiles.end(); ++pi)
  892. {
  893. files.insert(*pi);
  894. }
  895. }
  896. if ( ofs )
  897. {
  898. ofs << "Upload files:" << std::endl;
  899. int cnt = 0;
  900. cmCTest::SetOfStrings::iterator it;
  901. for ( it = files.begin(); it != files.end(); ++ it )
  902. {
  903. ofs << cnt << "\t" << it->c_str() << std::endl;
  904. cnt ++;
  905. }
  906. }
  907. cmCTestLog(this->CTest, HANDLER_OUTPUT, "Submit files (using "
  908. << this->CTest->GetCTestConfiguration("DropMethod") << ")"
  909. << std::endl);
  910. const char* specificTrack = this->CTest->GetSpecificTrack();
  911. if ( specificTrack )
  912. {
  913. cmCTestLog(this->CTest, HANDLER_OUTPUT, " Send to track: "
  914. << specificTrack << std::endl);
  915. }
  916. this->SetLogFile(&ofs);
  917. cmStdString dropMethod(this->CTest->GetCTestConfiguration("DropMethod"));
  918. if ( dropMethod == "" || dropMethod == "ftp" )
  919. {
  920. ofs << "Using drop method: FTP" << std::endl;
  921. cmCTestLog(this->CTest, HANDLER_OUTPUT, " Using FTP submit method"
  922. << std::endl
  923. << " Drop site: ftp://");
  924. std::string url = "ftp://";
  925. url += cmCTest::MakeURLSafe(
  926. this->CTest->GetCTestConfiguration("DropSiteUser")) + ":" +
  927. cmCTest::MakeURLSafe(this->CTest->GetCTestConfiguration(
  928. "DropSitePassword")) + "@" +
  929. this->CTest->GetCTestConfiguration("DropSite") +
  930. cmCTest::MakeURLSafe(
  931. this->CTest->GetCTestConfiguration("DropLocation"));
  932. if ( this->CTest->GetCTestConfiguration("DropSiteUser").size() > 0 )
  933. {
  934. cmCTestLog(this->CTest, HANDLER_OUTPUT,
  935. this->CTest->GetCTestConfiguration(
  936. "DropSiteUser").c_str());
  937. if ( this->CTest->GetCTestConfiguration("DropSitePassword").size() > 0 )
  938. {
  939. cmCTestLog(this->CTest, HANDLER_OUTPUT, ":******");
  940. }
  941. cmCTestLog(this->CTest, HANDLER_OUTPUT, "@");
  942. }
  943. cmCTestLog(this->CTest, HANDLER_OUTPUT,
  944. this->CTest->GetCTestConfiguration("DropSite")
  945. << this->CTest->GetCTestConfiguration("DropLocation") << std::endl);
  946. if ( !this->SubmitUsingFTP(buildDirectory + "/Testing/"
  947. + this->CTest->GetCurrentTag(),
  948. files, prefix, url) )
  949. {
  950. cmCTestLog(this->CTest, ERROR_MESSAGE,
  951. " Problems when submitting via FTP"
  952. << std::endl);
  953. ofs << " Problems when submitting via FTP" << std::endl;
  954. return -1;
  955. }
  956. if(!this->CDash)
  957. {
  958. cmCTestLog(this->CTest, HANDLER_OUTPUT, " Using HTTP trigger method"
  959. << std::endl
  960. << " Trigger site: "
  961. << this->CTest->GetCTestConfiguration("TriggerSite")
  962. << std::endl);
  963. if ( !this->
  964. TriggerUsingHTTP(files, prefix,
  965. this->CTest->GetCTestConfiguration("TriggerSite")))
  966. {
  967. cmCTestLog(this->CTest, ERROR_MESSAGE,
  968. " Problems when triggering via HTTP" << std::endl);
  969. ofs << " Problems when triggering via HTTP" << std::endl;
  970. return -1;
  971. }
  972. cmCTestLog(this->CTest, HANDLER_OUTPUT, " Submission successful"
  973. << std::endl);
  974. ofs << " Submission successful" << std::endl;
  975. return 0;
  976. }
  977. }
  978. else if ( dropMethod == "http" || dropMethod == "https" )
  979. {
  980. std::string url = dropMethod;
  981. url += "://";
  982. ofs << "Using drop method: " << dropMethod << std::endl;
  983. cmCTestLog(this->CTest, HANDLER_OUTPUT, " Using HTTP submit method"
  984. << std::endl
  985. << " Drop site:" << url);
  986. if ( this->CTest->GetCTestConfiguration("DropSiteUser").size() > 0 )
  987. {
  988. url += this->CTest->GetCTestConfiguration("DropSiteUser");
  989. cmCTestLog(this->CTest, HANDLER_OUTPUT,
  990. this->CTest->GetCTestConfiguration("DropSiteUser").c_str());
  991. if ( this->CTest->GetCTestConfiguration("DropSitePassword").size() > 0 )
  992. {
  993. url += ":" + this->CTest->GetCTestConfiguration("DropSitePassword");
  994. cmCTestLog(this->CTest, HANDLER_OUTPUT, ":******");
  995. }
  996. url += "@";
  997. cmCTestLog(this->CTest, HANDLER_OUTPUT, "@");
  998. }
  999. url += this->CTest->GetCTestConfiguration("DropSite") +
  1000. this->CTest->GetCTestConfiguration("DropLocation");
  1001. cmCTestLog(this->CTest, HANDLER_OUTPUT,
  1002. this->CTest->GetCTestConfiguration("DropSite")
  1003. << this->CTest->GetCTestConfiguration("DropLocation") << std::endl);
  1004. if ( !this->SubmitUsingHTTP(buildDirectory + "/Testing/" +
  1005. this->CTest->GetCurrentTag(), files, prefix, url) )
  1006. {
  1007. cmCTestLog(this->CTest, ERROR_MESSAGE,
  1008. " Problems when submitting via HTTP" << std::endl);
  1009. ofs << " Problems when submitting via HTTP" << std::endl;
  1010. return -1;
  1011. }
  1012. if(!this->CDash)
  1013. {
  1014. cmCTestLog(this->CTest, HANDLER_OUTPUT, " Using HTTP trigger method"
  1015. << std::endl
  1016. << " Trigger site: "
  1017. << this->CTest->GetCTestConfiguration("TriggerSite")
  1018. << std::endl);
  1019. if ( !this->
  1020. TriggerUsingHTTP(files, prefix,
  1021. this->CTest->GetCTestConfiguration("TriggerSite")))
  1022. {
  1023. cmCTestLog(this->CTest, ERROR_MESSAGE,
  1024. " Problems when triggering via HTTP" << std::endl);
  1025. ofs << " Problems when triggering via HTTP" << std::endl;
  1026. return -1;
  1027. }
  1028. }
  1029. cmCTestLog(this->CTest, HANDLER_OUTPUT, " Submission successful"
  1030. << std::endl);
  1031. ofs << " Submission successful" << std::endl;
  1032. return 0;
  1033. }
  1034. else if ( dropMethod == "xmlrpc" )
  1035. {
  1036. ofs << "Using drop method: XML-RPC" << std::endl;
  1037. cmCTestLog(this->CTest, HANDLER_OUTPUT, " Using XML-RPC submit method"
  1038. << std::endl);
  1039. std::string url = this->CTest->GetCTestConfiguration("DropSite");
  1040. prefix = this->CTest->GetCTestConfiguration("DropLocation");
  1041. if ( !this->SubmitUsingXMLRPC(buildDirectory + "/Testing/" +
  1042. this->CTest->GetCurrentTag(), files, prefix, url) )
  1043. {
  1044. cmCTestLog(this->CTest, ERROR_MESSAGE,
  1045. " Problems when submitting via XML-RPC" << std::endl);
  1046. ofs << " Problems when submitting via XML-RPC" << std::endl;
  1047. return -1;
  1048. }
  1049. cmCTestLog(this->CTest, HANDLER_OUTPUT, " Submission successful"
  1050. << std::endl);
  1051. ofs << " Submission successful" << std::endl;
  1052. return 0;
  1053. }
  1054. else if ( dropMethod == "scp" )
  1055. {
  1056. std::string url;
  1057. std::string oldWorkingDirectory;
  1058. if ( this->CTest->GetCTestConfiguration("DropSiteUser").size() > 0 )
  1059. {
  1060. url += this->CTest->GetCTestConfiguration("DropSiteUser") + "@";
  1061. }
  1062. url += this->CTest->GetCTestConfiguration("DropSite") + ":" +
  1063. this->CTest->GetCTestConfiguration("DropLocation");
  1064. // change to the build directory so that we can uses a relative path
  1065. // on windows since scp dosn't support "c:" a drive in the path
  1066. oldWorkingDirectory = cmSystemTools::GetCurrentWorkingDirectory();
  1067. cmSystemTools::ChangeDirectory(buildDirectory.c_str());
  1068. if ( !this->SubmitUsingSCP(
  1069. this->CTest->GetCTestConfiguration("ScpCommand"),
  1070. "Testing/"+this->CTest->GetCurrentTag(), files, prefix, url) )
  1071. {
  1072. cmSystemTools::ChangeDirectory(oldWorkingDirectory.c_str());
  1073. cmCTestLog(this->CTest, ERROR_MESSAGE,
  1074. " Problems when submitting via SCP"
  1075. << std::endl);
  1076. ofs << " Problems when submitting via SCP" << std::endl;
  1077. return -1;
  1078. }
  1079. cmSystemTools::ChangeDirectory(oldWorkingDirectory.c_str());
  1080. cmCTestLog(this->CTest, HANDLER_OUTPUT, " Submission successful"
  1081. << std::endl);
  1082. ofs << " Submission successful" << std::endl;
  1083. return 0;
  1084. }
  1085. else if ( dropMethod == "cp" )
  1086. {
  1087. std::string location
  1088. = this->CTest->GetCTestConfiguration("DropLocation");
  1089. // change to the build directory so that we can uses a relative path
  1090. // on windows since scp dosn't support "c:" a drive in the path
  1091. std::string
  1092. oldWorkingDirectory = cmSystemTools::GetCurrentWorkingDirectory();
  1093. cmSystemTools::ChangeDirectory(buildDirectory.c_str());
  1094. cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT, " Change directory: "
  1095. << buildDirectory.c_str() << std::endl);
  1096. if ( !this->SubmitUsingCP(
  1097. "Testing/"+this->CTest->GetCurrentTag(),
  1098. files,
  1099. prefix,
  1100. location) )
  1101. {
  1102. cmSystemTools::ChangeDirectory(oldWorkingDirectory.c_str());
  1103. cmCTestLog(this->CTest, ERROR_MESSAGE,
  1104. " Problems when submitting via CP"
  1105. << std::endl);
  1106. ofs << " Problems when submitting via cp" << std::endl;
  1107. return -1;
  1108. }
  1109. cmSystemTools::ChangeDirectory(oldWorkingDirectory.c_str());
  1110. cmCTestLog(this->CTest, HANDLER_OUTPUT, " Submission successful"
  1111. << std::endl);
  1112. ofs << " Submission successful" << std::endl;
  1113. return 0;
  1114. }
  1115. cmCTestLog(this->CTest, ERROR_MESSAGE, " Unknown submission method: \""
  1116. << dropMethod << "\"" << std::endl);
  1117. return -1;
  1118. }
  1119. //----------------------------------------------------------------------------
  1120. std::string cmCTestSubmitHandler::GetSubmitResultsPrefix()
  1121. {
  1122. std::string name = this->CTest->GetCTestConfiguration("Site") +
  1123. "___" + this->CTest->GetCTestConfiguration("BuildName") +
  1124. "___" + this->CTest->GetCurrentTag() + "-" +
  1125. this->CTest->GetTestModelString() + "___XML___";
  1126. return name;
  1127. }
  1128. //----------------------------------------------------------------------------
  1129. void cmCTestSubmitHandler::SelectParts(std::set<cmCTest::Part> const& parts)
  1130. {
  1131. // Check whether each part is selected.
  1132. for(cmCTest::Part p = cmCTest::PartStart;
  1133. p != cmCTest::PartCount; p = cmCTest::Part(p+1))
  1134. {
  1135. this->SubmitPart[p] =
  1136. (std::set<cmCTest::Part>::const_iterator(parts.find(p)) != parts.end());
  1137. }
  1138. }
  1139. //----------------------------------------------------------------------------
  1140. void cmCTestSubmitHandler::SelectFiles(cmCTest::SetOfStrings const& files)
  1141. {
  1142. cmCTest::SetOfStrings::const_iterator it;
  1143. for (it = files.begin(); it != files.end(); ++it)
  1144. {
  1145. this->Files.insert(*it);
  1146. }
  1147. }