cmCTestSubmitHandler.cxx 42 KB

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