cmCTest.cxx 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542
  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 "cmCTest.h"
  14. #include "cmRegularExpression.h"
  15. #include "cmSystemTools.h"
  16. #include "cmListFileCache.h"
  17. #ifdef HAVE_CURL
  18. # include "cmCTestSubmit.h"
  19. #endif
  20. #include <stdio.h>
  21. #include <time.h>
  22. static std::string CleanString(std::string str)
  23. {
  24. std::string::size_type spos = str.find_first_not_of(" \n\t");
  25. std::string::size_type epos = str.find_last_not_of(" \n\t");
  26. if ( spos == str.npos )
  27. {
  28. return std::string();
  29. }
  30. if ( epos != str.npos )
  31. {
  32. epos = epos - spos + 1;
  33. }
  34. return str.substr(spos, epos);
  35. }
  36. static std::string CurrentTime()
  37. {
  38. time_t currenttime = time(0);
  39. return ::CleanString(ctime(&currenttime));
  40. }
  41. static const char* cmCTestErrorMatches[] = {
  42. "^[Bb]us [Ee]rror",
  43. "^[Ss]egmentation [Vv]iolation",
  44. "^[Ss]egmentation [Ff]ault",
  45. "([^ :]+):([0-9]+): ([^ \\t])",
  46. "([^:]+): error[ \\t]*[0-9]+[ \\t]*:",
  47. "^Error ([0-9]+):",
  48. "^Error ",
  49. "^\"[^\"]+\", line [0-9]+: [^Ww]",
  50. "^cc[^C]*CC: ERROR File = ([^,]+), Line = ([0-9]+)",
  51. "^ld([^:])*:([ \\t])*ERROR([^:])*:",
  52. "^ild:([ \\t])*\\(undefined symbol\\)",
  53. "([^ :]+) : (error|fatal error|catastrophic error)",
  54. "([^:]+): (Error:|error|undefined reference|multiply defined)",
  55. "([^:]+)\\(([^\\)]+)\\) : (error|fatal error|catastrophic error)",
  56. "^fatal error C[0-9]+:",
  57. ": syntax error ",
  58. "^collect2: ld returned 1 exit status",
  59. "Unsatisfied symbols:",
  60. "Undefined symbols:",
  61. "^Undefined[ \\t]+first referenced",
  62. "^CMake Error:",
  63. ":[ \\t]cannot find",
  64. 0
  65. };
  66. static const char* cmCTestErrorExceptions[] = {
  67. 0
  68. };
  69. static const char* cmCTestWarningMatches[] = {
  70. "([^ :]+):([0-9]+): warning:",
  71. "^cc[^C]*CC: WARNING File = ([^,]+), Line = ([0-9]+)",
  72. "^ld([^:])*:([ \\t])*WARNING([^:])*:",
  73. "([^:]+): warning ([0-9]+):",
  74. "^\"[^\"]+\", line [0-9]+: [Ww]arning",
  75. "([^:]+): warning[ \\t]*[0-9]+[ \\t]*:",
  76. "^Warning ([0-9]+):",
  77. "^Warning ",
  78. "([^ :]+) : warning",
  79. "([^:]+): warning",
  80. 0
  81. };
  82. static const char* cmCTestWarningExceptions[] = {
  83. "/usr/openwin/include/X11/Xlib\\.h:[0-9]+: warning: ANSI C\\+\\+ forbids declaration",
  84. "/usr/openwin/include/X11/Xutil\\.h:[0-9]+: warning: ANSI C\\+\\+ forbids declaration",
  85. "/usr/openwin/include/X11/XResource\\.h:[0-9]+: warning: ANSI C\\+\\+ forbids declaration",
  86. "WARNING 84 :",
  87. "WARNING 47 :",
  88. "makefile:",
  89. "Makefile:",
  90. "warning: Clock skew detected. Your build may be incomplete.",
  91. "/usr/openwin/include/GL/[^:]+:",
  92. "bind_at_load",
  93. "XrmQGetResource",
  94. "IceFlush",
  95. "warning LNK4089: all references to .GDI32.dll. discarded by .OPT:REF",
  96. "warning LNK4089: all references to .USER32.dll. discarded by .OPT:REF",
  97. "ld32: WARNING 85: definition of dataKey in",
  98. 0
  99. };
  100. std::string cmCTest::MakeXMLSafe(const std::string& str)
  101. {
  102. std::string::size_type pos = 0;
  103. cmOStringStream ost;
  104. char buffer[10];
  105. for ( pos = 0; pos < str.size(); pos ++ )
  106. {
  107. char ch = str[pos];
  108. if ( ch > 126 )
  109. {
  110. sprintf(buffer, "&%x", (int)ch);
  111. ost << buffer;
  112. }
  113. else
  114. {
  115. switch ( ch )
  116. {
  117. case '&': ost << "&amp;"; break;
  118. case '<': ost << "&lt;"; break;
  119. case '>': ost << "&gt;"; break;
  120. default: ost << ch;
  121. }
  122. }
  123. }
  124. return ost.str();
  125. }
  126. bool TryExecutable(const char *dir, const char *file,
  127. std::string *fullPath, const char *subdir)
  128. {
  129. // try current directory
  130. std::string tryPath;
  131. if (dir && strcmp(dir,""))
  132. {
  133. tryPath = dir;
  134. tryPath += "/";
  135. }
  136. if (subdir && strcmp(subdir,""))
  137. {
  138. tryPath += subdir;
  139. tryPath += "/";
  140. }
  141. tryPath += file;
  142. if(cmSystemTools::FileExists(tryPath.c_str()))
  143. {
  144. *fullPath = cmSystemTools::CollapseFullPath(tryPath.c_str());
  145. return true;
  146. }
  147. tryPath += cmSystemTools::GetExecutableExtension();
  148. if(cmSystemTools::FileExists(tryPath.c_str()))
  149. {
  150. *fullPath = cmSystemTools::CollapseFullPath(tryPath.c_str());
  151. return true;
  152. }
  153. return false;
  154. }
  155. cmCTest::cmCTest()
  156. {
  157. m_UseIncludeRegExp = false;
  158. m_UseExcludeRegExp = false;
  159. m_UseExcludeRegExpFirst = false;
  160. m_Verbose = false;
  161. m_DartMode = false;
  162. m_ShowOnly = false;
  163. int cc;
  164. for ( cc=0; cc < cmCTest::LAST_TEST; cc ++ )
  165. {
  166. m_Tests[cc] = 0;
  167. }
  168. }
  169. void cmCTest::Initialize()
  170. {
  171. m_ToplevelPath = cmSystemTools::GetCurrentWorkingDirectory();
  172. // parse the dart test file
  173. std::ifstream fin("DartConfiguration.tcl");
  174. if(!fin)
  175. {
  176. return;
  177. }
  178. char buffer[1024];
  179. while ( fin )
  180. {
  181. buffer[0] = 0;
  182. fin.getline(buffer, 1023);
  183. buffer[1023] = 0;
  184. std::string line = ::CleanString(buffer);
  185. if(line.size() == 0)
  186. {
  187. continue;
  188. }
  189. while ( fin && (line[line.size()-1] == '\\') )
  190. {
  191. line = line.substr(0, line.size()-1);
  192. buffer[0] = 0;
  193. fin.getline(buffer, 1023);
  194. buffer[1023] = 0;
  195. line += ::CleanString(buffer);
  196. }
  197. if ( line[0] == '#' )
  198. {
  199. continue;
  200. }
  201. std::string::size_type cpos = line.find_first_of(":");
  202. if ( cpos == line.npos )
  203. {
  204. continue;
  205. }
  206. std::string key = line.substr(0, cpos);
  207. std::string value = ::CleanString(line.substr(cpos+1, line.npos));
  208. m_DartConfiguration[key] = value;
  209. }
  210. fin.close();
  211. if ( m_DartMode )
  212. {
  213. std::string testingDir = m_ToplevelPath + "/Testing/CDart";
  214. if ( cmSystemTools::FileExists(testingDir.c_str()) )
  215. {
  216. if ( !cmSystemTools::FileIsDirectory(testingDir.c_str()) )
  217. {
  218. std::cerr << "File " << testingDir << " is in the place of the testing directory"
  219. << std::endl;
  220. return;
  221. }
  222. }
  223. else
  224. {
  225. if ( !cmSystemTools::MakeDirectory(testingDir.c_str()) )
  226. {
  227. std::cerr << "Cannot create directory " << testingDir
  228. << std::endl;
  229. return;
  230. }
  231. }
  232. std::string tagfile = testingDir + "/TAG";
  233. std::ifstream tfin(tagfile.c_str());
  234. std::string tag;
  235. time_t tctime = time(0);
  236. struct tm *lctime = gmtime(&tctime);
  237. if ( tfin )
  238. {
  239. tfin >> tag;
  240. tfin.close();
  241. int year = 0;
  242. int mon = 0;
  243. int day = 0;
  244. int hour = 0;
  245. int min = 0;
  246. sscanf(tag.c_str(), "%04d%02d%02d-%02d%02d",
  247. &year, &mon, &day, &hour, &min);
  248. if ( year != lctime->tm_year + 1900 ||
  249. mon != lctime->tm_mon+1 ||
  250. day != lctime->tm_mday )
  251. {
  252. tag = "";
  253. }
  254. }
  255. if ( tag.size() == 0 )
  256. {
  257. char datestring[100];
  258. sprintf(datestring, "%04d%02d%02d-%02d%02d",
  259. lctime->tm_year + 1900,
  260. lctime->tm_mon+1,
  261. lctime->tm_mday,
  262. lctime->tm_hour,
  263. lctime->tm_min);
  264. tag = datestring;
  265. std::ofstream ofs(tagfile.c_str());
  266. if ( ofs )
  267. {
  268. ofs << tag << std::endl;
  269. }
  270. ofs.close();
  271. std::cout << "Create new tag: " << tag << std::endl;
  272. }
  273. m_CurrentTag = tag;
  274. }
  275. }
  276. bool cmCTest::SetTest(const char* ttype)
  277. {
  278. if ( cmSystemTools::LowerCase(ttype) == "all" )
  279. {
  280. m_Tests[cmCTest::ALL_TEST] = 1;
  281. }
  282. else if ( cmSystemTools::LowerCase(ttype) == "update" )
  283. {
  284. m_Tests[cmCTest::UPDATE_TEST] = 1;
  285. }
  286. else if ( cmSystemTools::LowerCase(ttype) == "configure" )
  287. {
  288. m_Tests[cmCTest::CONFIGURE_TEST] = 1;
  289. }
  290. else if ( cmSystemTools::LowerCase(ttype) == "build" )
  291. {
  292. m_Tests[cmCTest::BUILD_TEST] = 1;
  293. }
  294. else if ( cmSystemTools::LowerCase(ttype) == "test" )
  295. {
  296. m_Tests[cmCTest::TEST_TEST] = 1;
  297. }
  298. else if ( cmSystemTools::LowerCase(ttype) == "coverage" )
  299. {
  300. m_Tests[cmCTest::COVERAGE_TEST] = 1;
  301. }
  302. else if ( cmSystemTools::LowerCase(ttype) == "purify" )
  303. {
  304. m_Tests[cmCTest::PURIFY_TEST] = 1;
  305. }
  306. else if ( cmSystemTools::LowerCase(ttype) == "submit" )
  307. {
  308. m_Tests[cmCTest::SUBMIT_TEST] = 1;
  309. }
  310. else
  311. {
  312. std::cerr << "Don't know about test \"" << ttype << "\" yet..." << std::endl;
  313. return false;
  314. }
  315. return true;
  316. }
  317. void cmCTest::Finalize()
  318. {
  319. }
  320. std::string cmCTest::FindExecutable(const char *exe)
  321. {
  322. std::string fullPath = "";
  323. std::string dir;
  324. std::string file;
  325. cmSystemTools::SplitProgramPath(exe, dir, file);
  326. if(m_ConfigType != "")
  327. {
  328. if(TryExecutable(dir.c_str(), file.c_str(), &fullPath,
  329. m_ConfigType.c_str()))
  330. {
  331. return fullPath;
  332. }
  333. dir += "/";
  334. dir += m_ConfigType;
  335. dir += "/";
  336. dir += file;
  337. cmSystemTools::Error("config type specified on the command line, but test executable not found.",
  338. dir.c_str());
  339. return "";
  340. }
  341. if (TryExecutable(dir.c_str(),file.c_str(),&fullPath,"."))
  342. {
  343. return fullPath;
  344. }
  345. if (TryExecutable(dir.c_str(),file.c_str(),&fullPath,""))
  346. {
  347. return fullPath;
  348. }
  349. if (TryExecutable(dir.c_str(),file.c_str(),&fullPath,"Release"))
  350. {
  351. return fullPath;
  352. }
  353. if (TryExecutable(dir.c_str(),file.c_str(),&fullPath,"Debug"))
  354. {
  355. return fullPath;
  356. }
  357. if (TryExecutable(dir.c_str(),file.c_str(),&fullPath,"MinSizeRel"))
  358. {
  359. return fullPath;
  360. }
  361. if (TryExecutable(dir.c_str(),file.c_str(),&fullPath,"RelWithDebInfo"))
  362. {
  363. return fullPath;
  364. }
  365. // if everything else failed, check the users path
  366. if (dir != "")
  367. {
  368. std::string path = cmSystemTools::FindProgram(file.c_str());
  369. if (path != "")
  370. {
  371. return path;
  372. }
  373. }
  374. return fullPath;
  375. }
  376. int cmCTest::UpdateDirectory()
  377. {
  378. std::string cvsCommand = m_DartConfiguration["CVSCommand"];
  379. if ( cvsCommand.size() == 0 )
  380. {
  381. std::cerr << "Cannot find CVSCommand key in the DartConfiguration.tcl" << std::endl;
  382. return 1;
  383. }
  384. std::string cvsOptions = m_DartConfiguration["CVSUpdateOptions"];
  385. if ( cvsOptions.size() == 0 )
  386. {
  387. std::cerr << "Cannot find CVSUpdateOptions key in the DartConfiguration.tcl" << std::endl;
  388. return 1;
  389. }
  390. std::string sourceDirectory = m_DartConfiguration["SourceDirectory"];
  391. if ( sourceDirectory.size() == 0 )
  392. {
  393. std::cerr << "Cannot find SourceDirectory key in the DartConfiguration.tcl" << std::endl;
  394. return 1;
  395. }
  396. std::string command = cvsCommand + " update " + cvsOptions;
  397. std::string output;
  398. int retVal = 0;
  399. bool res = true;
  400. if ( !m_ShowOnly )
  401. {
  402. res = cmSystemTools::RunCommand(command.c_str(), output,
  403. retVal, sourceDirectory.c_str(),
  404. m_Verbose);
  405. }
  406. else
  407. {
  408. std::cout << "Update with command: " << command << std::endl;
  409. }
  410. if (! res || retVal )
  411. {
  412. std::cerr << "Error(s) when updating the project" << std::endl;
  413. return 1;
  414. }
  415. return 0;
  416. }
  417. int cmCTest::ConfigureDirectory()
  418. {
  419. std::string cCommand = m_DartConfiguration["ConfigureCommand"];
  420. if ( cCommand.size() == 0 )
  421. {
  422. std::cerr << "Cannot find ConfigureCommand key in the DartConfiguration.tcl"
  423. << std::endl;
  424. return 1;
  425. }
  426. std::string buildDirectory = m_DartConfiguration["BuildDirectory"];
  427. if ( buildDirectory.size() == 0 )
  428. {
  429. std::cerr << "Cannot find BuildDirectory key in the DartConfiguration.tcl" << std::endl;
  430. return 1;
  431. }
  432. std::string output;
  433. int retVal = 0;
  434. bool res = true;
  435. if ( !m_ShowOnly )
  436. {
  437. res = cmSystemTools::RunCommand(cCommand.c_str(), output,
  438. retVal, buildDirectory.c_str(),
  439. m_Verbose);
  440. }
  441. else
  442. {
  443. std::cout << "Configure with command: " << cCommand << std::endl;
  444. }
  445. if (! res || retVal )
  446. {
  447. std::cerr << "Error(s) when updating the project" << std::endl;
  448. return 1;
  449. }
  450. return 0;
  451. }
  452. int cmCTest::BuildDirectory()
  453. {
  454. std::string makeCommand = m_DartConfiguration["MakeCommand"];
  455. if ( makeCommand.size() == 0 )
  456. {
  457. std::cerr << "Cannot find MakeCommand key in the DartConfiguration.tcl" << std::endl;
  458. return 1;
  459. }
  460. std::string buildDirectory = m_DartConfiguration["BuildDirectory"];
  461. if ( buildDirectory.size() == 0 )
  462. {
  463. std::cerr << "Cannot find BuildDirectory key in the DartConfiguration.tcl" << std::endl;
  464. return 1;
  465. }
  466. m_StartBuild = ::CurrentTime();
  467. std::string output;
  468. int retVal = 0;
  469. bool res = true;
  470. if ( !m_ShowOnly )
  471. {
  472. res = cmSystemTools::RunCommand(makeCommand.c_str(), output,
  473. retVal, buildDirectory.c_str(),
  474. m_Verbose);
  475. }
  476. else
  477. {
  478. std::cout << "Build with command: " << makeCommand << std::endl;
  479. }
  480. m_EndBuild = ::CurrentTime();
  481. if (! res || retVal )
  482. {
  483. std::cerr << "Error(s) when building project" << std::endl;
  484. }
  485. // Parsing of output for errors and warnings.
  486. std::vector<cmStdString> lines;
  487. cmSystemTools::Split(output.c_str(), lines);
  488. std::ofstream ofs;
  489. if ( this->OpenOutputFile("Temporary", "LastBuild.log", ofs) )
  490. {
  491. ofs << output;
  492. ofs.close();
  493. }
  494. else
  495. {
  496. std::cerr << "Cannot create LastBuild.log file" << std::endl;
  497. }
  498. // Lines are marked:
  499. // 0 - nothing
  500. // 1 - error
  501. // > 1 - warning
  502. std::vector<int> markedLines(lines.size(), 0);
  503. int cc;
  504. // Errors
  505. for ( cc = 0; cmCTestErrorMatches[cc]; cc ++ )
  506. {
  507. cmRegularExpression re(cmCTestErrorMatches[cc]);
  508. std::vector<std::string>::size_type kk;
  509. for ( kk = 0; kk < lines.size(); kk ++ )
  510. {
  511. if ( re.find(lines[kk]) )
  512. {
  513. markedLines[kk] = 1;
  514. }
  515. }
  516. }
  517. // Warnings
  518. for ( cc = 0; cmCTestWarningMatches[cc]; cc ++ )
  519. {
  520. cmRegularExpression re(cmCTestWarningMatches[cc]);
  521. std::vector<std::string>::size_type kk;
  522. for ( kk = 0; kk < lines.size(); kk ++ )
  523. {
  524. if ( re.find(lines[kk]) )
  525. {
  526. markedLines[kk] += 2;
  527. }
  528. }
  529. }
  530. // Errors exceptions
  531. for ( cc = 0; cmCTestErrorExceptions[cc]; cc ++ )
  532. {
  533. cmRegularExpression re(cmCTestErrorExceptions[cc]);
  534. std::vector<int>::size_type kk;
  535. for ( kk =0; kk < markedLines.size(); kk ++ )
  536. {
  537. if ( markedLines[cc] == 1 )
  538. {
  539. if ( re.find(lines[kk]) )
  540. {
  541. markedLines[cc] = 0;
  542. }
  543. }
  544. }
  545. }
  546. // Warning exceptions
  547. for ( cc = 0; cmCTestWarningExceptions[cc]; cc ++ )
  548. {
  549. cmRegularExpression re(cmCTestWarningExceptions[cc]);
  550. std::vector<int>::size_type kk;
  551. for ( kk =0; kk < markedLines.size(); kk ++ )
  552. {
  553. if ( markedLines[cc] > 1 )
  554. {
  555. if ( re.find(lines[kk]) )
  556. {
  557. markedLines[cc] = 0;
  558. }
  559. }
  560. }
  561. }
  562. std::vector<cmCTestBuildErrorWarning> errorsWarnings;
  563. std::vector<int>::size_type kk;
  564. cmCTestBuildErrorWarning errorwarning;
  565. for ( kk =0; kk < markedLines.size(); kk ++ )
  566. {
  567. errorwarning.m_LineNumber = -1;
  568. bool found = false;
  569. if ( markedLines[kk] == 1 )
  570. {
  571. std::cout << "Error: " << lines[kk] << std::endl;
  572. errorwarning.m_Error = true;
  573. found = true;
  574. }
  575. else if ( markedLines[kk] > 1 )
  576. {
  577. std::cout << "Warning: " << lines[kk] << std::endl;
  578. errorwarning.m_Error = false;
  579. found = true;
  580. }
  581. if ( found )
  582. {
  583. errorwarning.m_LogLine = static_cast<int>(kk+1);
  584. errorwarning.m_Text = lines[kk];
  585. errorwarning.m_PreContext = "";
  586. errorwarning.m_PostContext = "";
  587. std::vector<int>::size_type jj;
  588. std::vector<int>::size_type ll = 0;
  589. if ( kk > 6 )
  590. {
  591. ll = kk - 6;
  592. }
  593. for ( jj = kk;
  594. jj > 0 && jj > ll /* && markedLines[jj] == 0 */;
  595. jj -- );
  596. for (; jj < kk; jj ++ )
  597. {
  598. errorwarning.m_PreContext += lines[jj] + "\n";
  599. }
  600. for ( jj = kk+1;
  601. jj < lines.size() && jj < kk + 7 /* && markedLines[jj] == 0*/;
  602. jj ++ )
  603. {
  604. errorwarning.m_PostContext += lines[jj] + "\n";
  605. }
  606. errorsWarnings.push_back(errorwarning);
  607. }
  608. }
  609. if( !this->OpenOutputFile("", "Build.xml", ofs) )
  610. {
  611. std::cerr << "Cannot create build XML file" << std::endl;
  612. return 1;
  613. }
  614. this->GenerateDartBuildOutput(ofs, errorsWarnings);
  615. return 0;
  616. }
  617. int cmCTest::CoverageDirectory()
  618. {
  619. std::vector<std::string> files;
  620. std::vector<std::string> cfiles;
  621. std::vector<std::string> cdirs;
  622. bool done = false;
  623. std::string::size_type cc;
  624. std::string glob;
  625. std::map<std::string, std::string> allsourcefiles;
  626. std::map<std::string, std::string> allbinaryfiles;
  627. std::string start_time = ::CurrentTime();
  628. // Find all source files.
  629. std::string sourceDirectory = m_DartConfiguration["SourceDirectory"];
  630. if ( sourceDirectory.size() == 0 )
  631. {
  632. std::cerr << "Cannot find SourceDirectory key in the DartConfiguration.tcl" << std::endl;
  633. return 1;
  634. }
  635. cdirs.push_back(sourceDirectory);
  636. while ( !done )
  637. {
  638. if ( cdirs.size() <= 0 )
  639. {
  640. break;
  641. }
  642. glob = cdirs[cdirs.size()-1] + "/*";
  643. //std::cout << "Glob: " << glob << std::endl;
  644. cdirs.pop_back();
  645. if ( cmSystemTools::SimpleGlob(glob, cfiles, 1) )
  646. {
  647. for ( cc = 0; cc < cfiles.size(); cc ++ )
  648. {
  649. allsourcefiles[cmSystemTools::GetFilenameName(cfiles[cc])] = cfiles[cc];
  650. }
  651. }
  652. if ( cmSystemTools::SimpleGlob(glob, cfiles, -1) )
  653. {
  654. for ( cc = 0; cc < cfiles.size(); cc ++ )
  655. {
  656. if ( cfiles[cc] != "." && cfiles[cc] != ".." )
  657. {
  658. cdirs.push_back(cfiles[cc]);
  659. }
  660. }
  661. }
  662. }
  663. // find all binary files
  664. cdirs.push_back(cmSystemTools::GetCurrentWorkingDirectory());
  665. while ( !done )
  666. {
  667. if ( cdirs.size() <= 0 )
  668. {
  669. break;
  670. }
  671. glob = cdirs[cdirs.size()-1] + "/*";
  672. //std::cout << "Glob: " << glob << std::endl;
  673. cdirs.pop_back();
  674. if ( cmSystemTools::SimpleGlob(glob, cfiles, 1) )
  675. {
  676. for ( cc = 0; cc < cfiles.size(); cc ++ )
  677. {
  678. allbinaryfiles[cmSystemTools::GetFilenameName(cfiles[cc])] = cfiles[cc];
  679. }
  680. }
  681. if ( cmSystemTools::SimpleGlob(glob, cfiles, -1) )
  682. {
  683. for ( cc = 0; cc < cfiles.size(); cc ++ )
  684. {
  685. if ( cfiles[cc] != "." && cfiles[cc] != ".." )
  686. {
  687. cdirs.push_back(cfiles[cc]);
  688. }
  689. }
  690. }
  691. }
  692. std::map<std::string, std::string>::iterator sit;
  693. for ( sit = allbinaryfiles.begin(); sit != allbinaryfiles.end(); sit ++ )
  694. {
  695. const std::string& fname = sit->second;
  696. //std::cout << "File: " << fname << std::endl;
  697. if ( strcmp(fname.substr(fname.size()-3, 3).c_str(), ".da") == 0 )
  698. {
  699. files.push_back(fname);
  700. }
  701. }
  702. if ( files.size() == 0 )
  703. {
  704. std::cout << "Cannot find any coverage information files (.da)" << std::endl;
  705. return 1;
  706. }
  707. std::ofstream log;
  708. if (!this->OpenOutputFile("Coverage", "Coverage.log", log))
  709. {
  710. std::cout << "Cannot open log file" << std::endl;
  711. return 1;
  712. }
  713. log.close();
  714. if (!this->OpenOutputFile("", "Coverage.xml", log))
  715. {
  716. std::cout << "Cannot open log file" << std::endl;
  717. return 1;
  718. }
  719. std::string opath = m_ToplevelPath + "/Testing/CDart/Coverage";
  720. for ( cc = 0; cc < files.size(); cc ++ )
  721. {
  722. std::string command = "gcov -l \"" + files[cc] + "\"";
  723. std::string output;
  724. int retVal = 0;
  725. //std::cout << "Run gcov on " << files[cc] << std::flush;
  726. bool res = true;
  727. if ( !m_ShowOnly )
  728. {
  729. res = cmSystemTools::RunCommand(command.c_str(), output,
  730. retVal, opath.c_str(),
  731. m_Verbose);
  732. }
  733. if ( res && retVal == 0 )
  734. {
  735. //std::cout << " - done" << std::endl;
  736. }
  737. else
  738. {
  739. //std::cout << " - fail" << std::endl;
  740. }
  741. }
  742. files.clear();
  743. glob = opath + "/*";
  744. if ( !cmSystemTools::SimpleGlob(glob, cfiles, 1) )
  745. {
  746. std::cout << "Cannot found any coverage files" << std::endl;
  747. return 1;
  748. }
  749. std::map<std::string, std::vector<std::string> > sourcefiles;
  750. for ( cc = 0; cc < cfiles.size(); cc ++ )
  751. {
  752. std::string& fname = cfiles[cc];
  753. //std::cout << "File: " << fname << std::endl;
  754. if ( strcmp(fname.substr(fname.size()-5, 5).c_str(), ".gcov") == 0 )
  755. {
  756. files.push_back(fname);
  757. std::string::size_type pos = fname.find(".da.");
  758. if ( pos != fname.npos )
  759. {
  760. pos += 4;
  761. std::string::size_type epos = fname.size() - pos - strlen(".gcov");
  762. std::string nf = fname.substr(pos, epos);
  763. //std::cout << "Substring: " << nf << std::endl;
  764. if ( allsourcefiles.find(nf) != allsourcefiles.end() ||
  765. allbinaryfiles.find(nf) != allbinaryfiles.end() )
  766. {
  767. std::vector<std::string> &cvec = sourcefiles[nf];
  768. cvec.push_back(fname);
  769. }
  770. }
  771. }
  772. }
  773. for ( cc = 0; cc < files.size(); cc ++ )
  774. {
  775. //std::cout << "File: " << files[cc] << std::endl;
  776. }
  777. std::map<std::string, std::vector<std::string> >::iterator it;
  778. cmCTest::tm_CoverageMap coverageresults;
  779. log << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
  780. << "<Site BuildName=\"" << m_DartConfiguration["BuildName"]
  781. << "\" BuildStamp=\"" << m_CurrentTag << "-Experimental\" Name=\""
  782. << m_DartConfiguration["Site"] << "\">\n"
  783. << "<Coverage>\n"
  784. << "\t<StartDateTime>" << start_time << "</StartDateTime>" << std::endl;
  785. int total_tested = 0;
  786. int total_untested = 0;
  787. for ( it = sourcefiles.begin(); it != sourcefiles.end(); it ++ )
  788. {
  789. //std::cerr << "Source file: " << it->first << std::endl;
  790. std::vector<std::string> &gfiles = it->second;
  791. for ( cc = 0; cc < gfiles.size(); cc ++ )
  792. {
  793. //std::cout << "\t" << gfiles[cc] << std::endl;
  794. std::ifstream ifile(gfiles[cc].c_str());
  795. ifile.seekg (0, std::ios::end);
  796. int length = ifile.tellg();
  797. ifile.seekg (0, std::ios::beg);
  798. char *buffer = new char [ length + 1 ];
  799. ifile.read(buffer, length);
  800. buffer [length] = 0;
  801. //std::cout << "Read: " << buffer << std::endl;
  802. std::vector<cmStdString> lines;
  803. cmSystemTools::Split(buffer, lines);
  804. delete [] buffer;
  805. cmCTest::cmCTestCoverage& cov = coverageresults[it->first];
  806. std::vector<int>& covlines = cov.m_Lines;
  807. if ( cov.m_FullPath == "" )
  808. {
  809. covlines.insert(covlines.begin(), lines.size(), -1);
  810. if ( allsourcefiles.find(it->first) != allsourcefiles.end() )
  811. {
  812. cov.m_FullPath = allsourcefiles[it->first];
  813. }
  814. else if ( allbinaryfiles.find(it->first) != allbinaryfiles.end() )
  815. {
  816. cov.m_FullPath = allbinaryfiles[it->first];
  817. }
  818. //std::cerr << "Full path: " << cov.m_FullPath << std::endl;
  819. }
  820. for ( cc = 0; cc < lines.size(); cc ++ )
  821. {
  822. std::string& line = lines[cc];
  823. std::string sub = line.substr(0, strlen(" ######"));
  824. int count = atoi(sub.c_str());
  825. if ( sub.compare(" ######") == 0 )
  826. {
  827. if ( covlines[cc] == -1 )
  828. {
  829. covlines[cc] = 0;
  830. }
  831. cov.m_UnTested ++;
  832. //std::cout << "Untested - ";
  833. }
  834. else if ( count > 0 )
  835. {
  836. if ( covlines[cc] == -1 )
  837. {
  838. covlines[cc] = 0;
  839. }
  840. cov.m_Tested ++;
  841. covlines[cc] += count;
  842. //std::cout << "Tested[" << count << "] - ";
  843. }
  844. //std::cout << line << std::endl;
  845. }
  846. }
  847. }
  848. //std::cerr << "Finalizing" << std::endl;
  849. cmCTest::tm_CoverageMap::iterator cit;
  850. int ccount = 0;
  851. std::ofstream cfileoutput;
  852. int cfileoutputcount = 0;
  853. char cfileoutputname[100];
  854. sprintf(cfileoutputname, "CoverageLog-%d.xml", cfileoutputcount++);
  855. if (!this->OpenOutputFile("", cfileoutputname, cfileoutput))
  856. {
  857. std::cout << "Cannot open log file" << std::endl;
  858. return 1;
  859. }
  860. std::string local_start_time = ::CurrentTime();
  861. std::string local_end_time;
  862. for ( cit = coverageresults.begin(); cit != coverageresults.end(); cit ++ )
  863. {
  864. if ( ccount == 100 )
  865. {
  866. local_end_time = ::CurrentTime();
  867. cfileoutput << "\t<EndDateTime>" << local_end_time << "</EndDateTime>\n"
  868. << "</CoverageLog>\n"
  869. << "</Site>" << std::endl;
  870. cfileoutput.close();
  871. sprintf(cfileoutputname, "CoverageLog-%d.xml", cfileoutputcount++);
  872. if (!this->OpenOutputFile("", cfileoutputname, cfileoutput))
  873. {
  874. std::cout << "Cannot open log file" << std::endl;
  875. return 1;
  876. }
  877. ccount = 0;
  878. }
  879. if ( ccount == 0 )
  880. {
  881. local_start_time = ::CurrentTime();
  882. cfileoutput << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
  883. << "<Site BuildName=\"" << m_DartConfiguration["BuildName"]
  884. << "\" BuildStamp=\"" << m_CurrentTag << "-Experimental\" Name=\""
  885. << m_DartConfiguration["Site"] << "\">\n"
  886. << "<CoverageLog>\n"
  887. << "\t<StartDateTime>" << local_start_time << "</StartDateTime>" << std::endl;
  888. }
  889. //std::cerr << "Final process of Source file: " << cit->first << std::endl;
  890. cmCTest::cmCTestCoverage &cov = cit->second;
  891. std::ifstream ifile(cov.m_FullPath.c_str());
  892. ifile.seekg (0, std::ios::end);
  893. int length = ifile.tellg();
  894. ifile.seekg (0, std::ios::beg);
  895. char *buffer = new char [ length + 1 ];
  896. ifile.read(buffer, length);
  897. buffer [length] = 0;
  898. //std::cout << "Read: " << buffer << std::endl;
  899. std::vector<cmStdString> lines;
  900. cmSystemTools::Split(buffer, lines);
  901. delete [] buffer;
  902. cfileoutput << "\t<File Name=\"" << cit->first << "\" FullPath=\""
  903. << cov.m_FullPath << std::endl << "\">\n"
  904. << "\t\t<Report>" << std::endl;
  905. for ( cc = 0; cc < lines.size(); cc ++ )
  906. {
  907. cfileoutput << "\t\t<Line Number=\""
  908. << static_cast<int>(cc) << "\" Count=\""
  909. << cov.m_Lines[cc] << "\">"
  910. << lines[cc] << "</Line>" << std::endl;
  911. }
  912. cfileoutput << "\t\t</Report>\n"
  913. << "\t</File>" << std::endl;
  914. total_tested += cov.m_Tested;
  915. total_untested += cov.m_UnTested;
  916. float cper = 0;
  917. float cmet = 0;
  918. if ( total_tested + total_untested > 0 )
  919. {
  920. cper = (100 * static_cast<float>(cov.m_Tested)/
  921. static_cast<float>(cov.m_Tested + cov.m_UnTested));
  922. cmet = ( static_cast<float>(cov.m_Tested + 10) /
  923. static_cast<float>(cov.m_Tested + cov.m_UnTested + 10));
  924. }
  925. log << "\t<File Name=\"" << cit->first << "\" FullPath=\"" << cov.m_FullPath
  926. << "\" Covered=\"" << cov.m_Covered << "\">\n"
  927. << "\t\t<LOCTested>" << cov.m_Tested << "</LOCTested>\n"
  928. << "\t\t<LOCUnTested>" << cov.m_UnTested << "</LOCUnTested>\n"
  929. << "\t\t<PercentCoverage>" << cper << "</PercentCoverage>\n"
  930. << "\t\t<CoverageMetric>" << cmet << "</CoverageMetric>\n"
  931. << "\t</File>" << std::endl;
  932. }
  933. if ( ccount > 0 )
  934. {
  935. local_end_time = ::CurrentTime();
  936. cfileoutput << "\t<EndDateTime>" << local_end_time << "</EndDateTime>\n"
  937. << "</CoverageLog>\n"
  938. << "</Site>" << std::endl;
  939. cfileoutput.close();
  940. }
  941. int total_lines = total_tested + total_untested;
  942. float percent_coverage = 100 * static_cast<float>(total_tested) /
  943. static_cast<float>(total_lines);
  944. if ( total_lines == 0 )
  945. {
  946. percent_coverage = 0;
  947. }
  948. std::string end_time = ::CurrentTime();
  949. log << "\t<LOCTested>" << total_tested << "</LOCTested>\n"
  950. << "\t<LOCUntested>" << total_untested << "</LOCUntested>\n"
  951. << "\t<LOC>" << total_lines << "</LOC>\n"
  952. << "\t<PercentCoverage>" << percent_coverage << "</PercentCoverage>\n"
  953. << "\t<EndDateTime>" << end_time << "</EndDateTime>\n"
  954. << "</Coverage>\n"
  955. << "</Site>" << std::endl;
  956. std::cout << "\tCovered LOC: " << total_tested << std::endl
  957. << "\tNot covered LOC: " << total_untested << std::endl
  958. << "\tTotal LOC: " << total_lines << std::endl
  959. << "\tPercentage Coverage: " << percent_coverage << "%" << std::endl;
  960. std::cerr << "Coverage test is not yet implemented" << std::endl;
  961. return 1;
  962. }
  963. bool cmCTest::OpenOutputFile(const std::string& path,
  964. const std::string& name, std::ofstream& stream)
  965. {
  966. std::string testingDir = m_ToplevelPath + "/Testing/CDart";
  967. if ( path.size() > 0 )
  968. {
  969. testingDir += "/" + path;
  970. }
  971. if ( cmSystemTools::FileExists(testingDir.c_str()) )
  972. {
  973. if ( !cmSystemTools::FileIsDirectory(testingDir.c_str()) )
  974. {
  975. std::cerr << "File " << testingDir
  976. << " is in the place of the testing directory"
  977. << std::endl;
  978. return false;
  979. }
  980. }
  981. else
  982. {
  983. if ( !cmSystemTools::MakeDirectory(testingDir.c_str()) )
  984. {
  985. std::cerr << "Cannot create directory " << testingDir
  986. << std::endl;
  987. return false;
  988. }
  989. }
  990. std::string filename = testingDir + "/" + name;
  991. stream.open(filename.c_str());
  992. if( !stream )
  993. {
  994. return false;
  995. }
  996. return true;
  997. }
  998. void cmCTest::GenerateDartBuildOutput(std::ostream& os,
  999. std::vector<cmCTestBuildErrorWarning> ew)
  1000. {
  1001. os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
  1002. << "<Site BuildName=\"" << m_DartConfiguration["BuildName"]
  1003. << "\" BuildStamp=\"" << m_CurrentTag << "-Experimental\" Name=\""
  1004. << m_DartConfiguration["Site"] << "\">\n"
  1005. << "<Build>\n"
  1006. << "\t<StartDateTime>" << m_StartBuild << "</StartDateTime>\n"
  1007. << "<BuildCommand>"
  1008. << this->MakeXMLSafe(m_DartConfiguration["MakeCommand"])
  1009. << "</BuildCommand>" << std::endl;
  1010. std::vector<cmCTestBuildErrorWarning>::iterator it;
  1011. for ( it = ew.begin(); it != ew.end(); it++ )
  1012. {
  1013. cmCTestBuildErrorWarning *cm = &(*it);
  1014. os << "\t<" << (cm->m_Error ? "Error" : "Warning") << ">\n"
  1015. << "\t\t<BuildLogLine>" << cm->m_LogLine << "</BuildLogLine>\n"
  1016. << "\t\t<Text>" << this->MakeXMLSafe(cm->m_Text)
  1017. << "\n</Text>" << std::endl;
  1018. if ( cm->m_SourceFile.size() > 0 )
  1019. {
  1020. os << "\t\t<SourceFile>" << cm->m_SourceFile << "</SourceFile>"
  1021. << std::endl;
  1022. }
  1023. if ( cm->m_SourceFileTail.size() > 0 )
  1024. {
  1025. os << "\t\t<SourceFileTail>" << cm->m_SourceFileTail
  1026. << "</SourceFileTail>" << std::endl;
  1027. }
  1028. if ( cm->m_LineNumber >= 0 )
  1029. {
  1030. os << "\t\t<SourceLineNumber>" << cm->m_LineNumber
  1031. << "</SourceLineNumber>" << std::endl;
  1032. }
  1033. os << "\t\t<PreContext>" << this->MakeXMLSafe(cm->m_PreContext)
  1034. << "</PreContext>\n"
  1035. << "\t\t<PostContext>" << this->MakeXMLSafe(cm->m_PostContext)
  1036. << "</PostContext>\n"
  1037. << "\t\t<RepeatCount>0</RepeatCount>\n"
  1038. << "</" << (cm->m_Error ? "Error" : "Warning") << ">\n\n"
  1039. << std::endl;
  1040. }
  1041. os << "\t<Log Encoding=\"base64\" Compression=\"/bin/gzip\">\n\t</Log>\n"
  1042. << "\t<EndDateTime>" << m_EndBuild << "</EndDateTime>\n"
  1043. << "</Build>\n"
  1044. << "</Site>" << std::endl;
  1045. }
  1046. void cmCTest::ProcessDirectory(std::vector<std::string> &passed,
  1047. std::vector<std::string> &failed)
  1048. {
  1049. // does the DartTestfile.txt exist ?
  1050. if(!cmSystemTools::FileExists("DartTestfile.txt"))
  1051. {
  1052. return;
  1053. }
  1054. // parse the file
  1055. std::ifstream fin("DartTestfile.txt");
  1056. if(!fin)
  1057. {
  1058. return;
  1059. }
  1060. int firstTest = 1;
  1061. long line = 0;
  1062. cmRegularExpression ireg(this->m_IncludeRegExp.c_str());
  1063. cmRegularExpression ereg(this->m_ExcludeRegExp.c_str());
  1064. cmRegularExpression dartStuff("([\t\n ]*<DartMeasurement.*/DartMeasurement[a-zA-Z]*>[\t ]*[\n]*)");
  1065. bool parseError;
  1066. while ( fin )
  1067. {
  1068. cmListFileFunction lff;
  1069. if(cmListFileCache::ParseFunction(fin, lff, "DartTestfile.txt",
  1070. parseError, line))
  1071. {
  1072. const std::string& name = lff.m_Name;
  1073. const std::vector<cmListFileArgument>& args = lff.m_Arguments;
  1074. if (name == "SUBDIRS")
  1075. {
  1076. std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
  1077. for(std::vector<cmListFileArgument>::const_iterator j = args.begin();
  1078. j != args.end(); ++j)
  1079. {
  1080. std::string nwd = cwd + "/";
  1081. nwd += j->Value;
  1082. if (cmSystemTools::FileIsDirectory(nwd.c_str()))
  1083. {
  1084. cmSystemTools::ChangeDirectory(nwd.c_str());
  1085. this->ProcessDirectory(passed, failed);
  1086. }
  1087. }
  1088. // return to the original directory
  1089. cmSystemTools::ChangeDirectory(cwd.c_str());
  1090. }
  1091. if (name == "ADD_TEST")
  1092. {
  1093. if (this->m_UseExcludeRegExp &&
  1094. this->m_UseExcludeRegExpFirst &&
  1095. ereg.find(args[0].Value.c_str()))
  1096. {
  1097. continue;
  1098. }
  1099. if (this->m_UseIncludeRegExp && !ireg.find(args[0].Value.c_str()))
  1100. {
  1101. continue;
  1102. }
  1103. if (this->m_UseExcludeRegExp &&
  1104. !this->m_UseExcludeRegExpFirst &&
  1105. ereg.find(args[0].Value.c_str()))
  1106. {
  1107. continue;
  1108. }
  1109. cmCTestTestResult cres;
  1110. if (firstTest)
  1111. {
  1112. std::string nwd = cmSystemTools::GetCurrentWorkingDirectory();
  1113. std::cerr << "Changing directory into " << nwd.c_str() << "\n";
  1114. firstTest = 0;
  1115. }
  1116. cres.m_Name = args[0].Value;
  1117. if ( m_ShowOnly )
  1118. {
  1119. std::cout << args[0].Value << std::endl;
  1120. }
  1121. else
  1122. {
  1123. fprintf(stderr,"Testing %-30s ",args[0].Value.c_str());
  1124. fflush(stderr);
  1125. }
  1126. //std::cerr << "Testing " << args[0] << " ... ";
  1127. // find the test executable
  1128. std::string testCommand = this->FindExecutable(args[1].Value.c_str());
  1129. testCommand = cmSystemTools::ConvertToOutputPath(testCommand.c_str());
  1130. // continue if we did not find the executable
  1131. if (testCommand == "")
  1132. {
  1133. std::cerr << "Unable to find executable: " <<
  1134. args[1].Value.c_str() << "\n";
  1135. continue;
  1136. }
  1137. // add the arguments
  1138. std::vector<cmListFileArgument>::const_iterator j = args.begin();
  1139. ++j;
  1140. ++j;
  1141. for(;j != args.end(); ++j)
  1142. {
  1143. testCommand += " ";
  1144. testCommand += cmSystemTools::EscapeSpaces(j->Value.c_str());
  1145. }
  1146. /**
  1147. * Run an executable command and put the stdout in output.
  1148. */
  1149. std::string output;
  1150. int retVal = 0;
  1151. double clock_start, clock_finish;
  1152. clock_start = cmSystemTools::GetTime();
  1153. if ( m_Verbose )
  1154. {
  1155. std::cout << std::endl << "Test command: " << testCommand << std::endl;
  1156. }
  1157. bool res = true;
  1158. if ( !m_ShowOnly )
  1159. {
  1160. res = cmSystemTools::RunCommand(testCommand.c_str(), output,
  1161. retVal, 0, false);
  1162. }
  1163. clock_finish = cmSystemTools::GetTime();
  1164. cres.m_ExecutionTime = (double)(clock_finish - clock_start);
  1165. cres.m_FullCommandLine = testCommand;
  1166. if ( !m_ShowOnly )
  1167. {
  1168. if (!res || retVal != 0)
  1169. {
  1170. fprintf(stderr,"***Failed\n");
  1171. if (output != "")
  1172. {
  1173. if (dartStuff.find(output.c_str()))
  1174. {
  1175. cmSystemTools::ReplaceString(output,
  1176. dartStuff.match(1).c_str(),"");
  1177. }
  1178. if (output != "" && m_Verbose)
  1179. {
  1180. std::cerr << output.c_str() << "\n";
  1181. }
  1182. }
  1183. failed.push_back(args[0].Value);
  1184. }
  1185. else
  1186. {
  1187. fprintf(stderr," Passed\n");
  1188. if (output != "")
  1189. {
  1190. if (dartStuff.find(output.c_str()))
  1191. {
  1192. cmSystemTools::ReplaceString(output,
  1193. dartStuff.match(1).c_str(),"");
  1194. }
  1195. if (output != "" && m_Verbose)
  1196. {
  1197. std::cerr << output.c_str() << "\n";
  1198. }
  1199. }
  1200. passed.push_back(args[0].Value);
  1201. }
  1202. }
  1203. cres.m_Output = output;
  1204. cres.m_ReturnValue = retVal;
  1205. std::string nwd = cmSystemTools::GetCurrentWorkingDirectory();
  1206. if ( nwd.size() > m_ToplevelPath.size() )
  1207. {
  1208. nwd = "." + nwd.substr(m_ToplevelPath.size(), nwd.npos);
  1209. }
  1210. cres.m_Path = nwd;
  1211. cres.m_CompletionStatus = "Completed";
  1212. m_TestResults.push_back( cres );
  1213. }
  1214. }
  1215. }
  1216. }
  1217. int cmCTest::TestDirectory()
  1218. {
  1219. std::vector<std::string> passed;
  1220. std::vector<std::string> failed;
  1221. int total;
  1222. m_StartTest = ::CurrentTime();
  1223. this->ProcessDirectory(passed, failed);
  1224. m_EndTest = ::CurrentTime();
  1225. total = int(passed.size()) + int(failed.size());
  1226. if (total == 0)
  1227. {
  1228. if ( !m_ShowOnly )
  1229. {
  1230. std::cerr << "No tests were found!!!\n";
  1231. }
  1232. }
  1233. else
  1234. {
  1235. if (passed.size() && (m_UseIncludeRegExp || m_UseExcludeRegExp))
  1236. {
  1237. std::cerr << "\nThe following tests passed:\n";
  1238. for(std::vector<std::string>::iterator j = passed.begin();
  1239. j != passed.end(); ++j)
  1240. {
  1241. std::cerr << "\t" << *j << "\n";
  1242. }
  1243. }
  1244. float percent = float(passed.size()) * 100.0f / total;
  1245. fprintf(stderr,"\n%.0f%% tests passed, %i tests failed out of %i\n",
  1246. percent, int(failed.size()), total);
  1247. if (failed.size())
  1248. {
  1249. std::cerr << "\nThe following tests FAILED:\n";
  1250. for(std::vector<std::string>::iterator j = failed.begin();
  1251. j != failed.end(); ++j)
  1252. {
  1253. std::cerr << "\t" << *j << "\n";
  1254. }
  1255. }
  1256. }
  1257. if ( m_DartMode )
  1258. {
  1259. std::ofstream ofs;
  1260. if( !this->OpenOutputFile("", "Test.xml", ofs) )
  1261. {
  1262. std::cerr << "Cannot create testing XML file" << std::endl;
  1263. return 1;
  1264. }
  1265. this->GenerateDartOutput(ofs);
  1266. }
  1267. return int(failed.size());
  1268. }
  1269. int cmCTest::SubmitResults()
  1270. {
  1271. #ifdef HAVE_CURL
  1272. std::vector<std::string> files;
  1273. std::string prefix = this->GetSubmitResultsPrefix();
  1274. if ( this->CTestFileExists("Build.xml") )
  1275. {
  1276. files.push_back("Build.xml");
  1277. }
  1278. if ( this->CTestFileExists("Test.xml") )
  1279. {
  1280. files.push_back("Test.xml");
  1281. }
  1282. if ( this->CTestFileExists("Coverage.xml") )
  1283. {
  1284. files.push_back("Coverage.xml");
  1285. }
  1286. if ( this->CTestFileExists("Purify.xml") )
  1287. {
  1288. files.push_back("Purify.xml");
  1289. }
  1290. cmCTestSubmit submit;
  1291. if ( m_DartConfiguration["DropMethod"] == "" ||
  1292. m_DartConfiguration["DropMethod"] == "ftp" )
  1293. {
  1294. std::cout << "FTP submit method" << std::endl;
  1295. std::string url = "ftp://";
  1296. url += m_DartConfiguration["DropSiteUser"] + ":" +
  1297. m_DartConfiguration["DropSitePassword"] + "@" +
  1298. m_DartConfiguration["DropSite"] +
  1299. m_DartConfiguration["DropLocation"];
  1300. submit.SubmitUsingFTP(m_ToplevelPath+"/Testing/CDart", files, prefix, url);
  1301. }
  1302. else
  1303. {
  1304. std::cout << "SCP submit not yet implemented" << std::endl;
  1305. }
  1306. #endif
  1307. return 0;
  1308. }
  1309. bool cmCTest::CTestFileExists(const std::string& filename)
  1310. {
  1311. std::string testingDir = m_ToplevelPath + "/Testing/CDart/" +
  1312. filename;
  1313. return cmSystemTools::FileExists(testingDir.c_str());
  1314. }
  1315. std::string cmCTest::GetSubmitResultsPrefix()
  1316. {
  1317. std::string name = m_DartConfiguration["Site"] +
  1318. "___" + m_DartConfiguration["BuildName"] +
  1319. "___" + m_CurrentTag + "-Experimental___XML___";
  1320. return name;
  1321. }
  1322. void cmCTest::GenerateDartOutput(std::ostream& os)
  1323. {
  1324. if ( !m_DartMode )
  1325. {
  1326. return;
  1327. }
  1328. if ( m_TestResults.size() == 0 )
  1329. {
  1330. return;
  1331. }
  1332. os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
  1333. << "<Site BuildName=\"" << m_DartConfiguration["BuildName"]
  1334. << "\" BuildStamp=\"" << m_CurrentTag << "-Experimental\" Name=\""
  1335. << m_DartConfiguration["Site"] << "\">\n"
  1336. << "<Testing>\n"
  1337. << "\t<StartDateTime>" << m_StartTest << "</StartDateTime>\n"
  1338. << "\t<TestList>\n";
  1339. tm_TestResultsVector::size_type cc;
  1340. for ( cc = 0; cc < m_TestResults.size(); cc ++ )
  1341. {
  1342. cmCTestTestResult *result = &m_TestResults[cc];
  1343. os << "\t\t<Test>" << this->MakeXMLSafe(result->m_Path)
  1344. << "/" << this->MakeXMLSafe(result->m_Name)
  1345. << "</Test>" << std::endl;
  1346. }
  1347. os << "\t</TestList>\n";
  1348. for ( cc = 0; cc < m_TestResults.size(); cc ++ )
  1349. {
  1350. cmCTestTestResult *result = &m_TestResults[cc];
  1351. os << "\t<Test Status=\"" << (result->m_ReturnValue?"failed":"passed")
  1352. << "\">\n"
  1353. << "\t\t<Name>" << this->MakeXMLSafe(result->m_Name) << "</Name>\n"
  1354. << "\t\t<Path>" << this->MakeXMLSafe(result->m_Path) << "</Path>\n"
  1355. << "\t\t<FullName>" << this->MakeXMLSafe(result->m_Path)
  1356. << "/" << this->MakeXMLSafe(result->m_Name) << "</FullName>\n"
  1357. << "\t\t<FullCommandLine>"
  1358. << this->MakeXMLSafe(result->m_FullCommandLine)
  1359. << "</FullCommandLine>\n"
  1360. << "\t\t<Results>" << std::endl;
  1361. if ( result->m_ReturnValue )
  1362. {
  1363. os << "\t\t\t<NamedMeasurement type=\"text/string\" name=\"Exit Code\"><Value>"
  1364. << "CHILDSTATUS" << "</Value></NamedMeasurement>\n"
  1365. << "\t\t\t<NamedMeasurement type=\"text/string\" name=\"Exit Value\"><Value>"
  1366. << result->m_ReturnValue << "</Value></NamedMeasurement>" << std::endl;
  1367. }
  1368. os << "\t\t\t<NamedMeasurement type=\"numeric/double\" "
  1369. << "name=\"Execution Time\"><Value>"
  1370. << result->m_ExecutionTime << "</Value></NamedMeasurement>\n"
  1371. << "\t\t\t<NamedMeasurement type=\"text/string\" "
  1372. << "name=\"Completion Status\"><Value>"
  1373. << result->m_CompletionStatus << "</Value></NamedMeasurement>\n"
  1374. << "\t\t\t<Measurement>\n"
  1375. << "\t\t\t\t<Value>" << this->MakeXMLSafe(result->m_Output)
  1376. << "</Value>\n"
  1377. << "\t\t\t</Measurement>\n"
  1378. << "\t\t</Results>\n"
  1379. << "\t</Test>" << std::endl;
  1380. }
  1381. os << "\t<EndDateTime>" << m_EndTest << "</EndDateTime>\n"
  1382. << "</Testing>\n"
  1383. << "</Site>" << std::endl;
  1384. }
  1385. int cmCTest::ProcessTests()
  1386. {
  1387. int res = 0;
  1388. bool notest = true;
  1389. int cc;
  1390. for ( cc = 0; cc < LAST_TEST; cc ++ )
  1391. {
  1392. if ( m_Tests[cc] )
  1393. {
  1394. notest = false;
  1395. break;
  1396. }
  1397. }
  1398. if ( m_Tests[UPDATE_TEST] || m_Tests[ALL_TEST] )
  1399. {
  1400. res += this->UpdateDirectory();
  1401. }
  1402. if ( m_Tests[CONFIGURE_TEST] || m_Tests[ALL_TEST] )
  1403. {
  1404. res += this->ConfigureDirectory();
  1405. }
  1406. if ( m_Tests[BUILD_TEST] || m_Tests[ALL_TEST] )
  1407. {
  1408. res += this->BuildDirectory();
  1409. }
  1410. if ( m_Tests[TEST_TEST] || m_Tests[ALL_TEST] || notest )
  1411. {
  1412. res += this->TestDirectory();
  1413. }
  1414. if ( m_Tests[COVERAGE_TEST] || m_Tests[ALL_TEST] )
  1415. {
  1416. this->CoverageDirectory();
  1417. }
  1418. if ( m_Tests[PURIFY_TEST] || m_Tests[ALL_TEST] )
  1419. {
  1420. std::cerr << "Purify test is not yet implemented" << std::endl;
  1421. }
  1422. if ( m_Tests[SUBMIT_TEST] || m_Tests[ALL_TEST] )
  1423. {
  1424. #ifdef HAVE_CURL
  1425. this->SubmitResults();
  1426. #else
  1427. std::cerr << "Submit test is not yet implemented" << std::endl;
  1428. #endif
  1429. }
  1430. return res;
  1431. }