cmCTestTestHandler.cxx 50 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720
  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 "cmCTestTestHandler.h"
  14. #include "cmCTest.h"
  15. #include "cmake.h"
  16. #include "cmGeneratedFileStream.h"
  17. #include <cmsys/Process.h>
  18. #include <cmsys/RegularExpression.hxx>
  19. #include <cmsys/Base64.h>
  20. #include "cmMakefile.h"
  21. #include <stdlib.h>
  22. #include <math.h>
  23. #include <float.h>
  24. static const char* cmCTestMemCheckResultStrings[] = {
  25. "ABR",
  26. "ABW",
  27. "ABWL",
  28. "COR",
  29. "EXU",
  30. "FFM",
  31. "FIM",
  32. "FMM",
  33. "FMR",
  34. "FMW",
  35. "FUM",
  36. "IPR",
  37. "IPW",
  38. "MAF",
  39. "MLK",
  40. "MPK",
  41. "NPR",
  42. "ODS",
  43. "PAR",
  44. "PLK",
  45. "UMC",
  46. "UMR",
  47. 0
  48. };
  49. static const char* cmCTestMemCheckResultLongStrings[] = {
  50. "Threading Problem",
  51. "ABW",
  52. "ABWL",
  53. "COR",
  54. "EXU",
  55. "FFM",
  56. "FIM",
  57. "Mismatched deallocation",
  58. "FMR",
  59. "FMW",
  60. "FUM",
  61. "IPR",
  62. "IPW",
  63. "MAF",
  64. "Memory Leak",
  65. "Potential Memory Leak",
  66. "NPR",
  67. "ODS",
  68. "Invalid syscall param",
  69. "PLK",
  70. "Uninitialized Memory Conditional",
  71. "Uninitialized Memory Read",
  72. 0
  73. };
  74. bool TryExecutable(const char *dir, const char *file,
  75. std::string *fullPath, const char *subdir)
  76. {
  77. // try current directory
  78. std::string tryPath;
  79. if (dir && strcmp(dir,""))
  80. {
  81. tryPath = dir;
  82. tryPath += "/";
  83. }
  84. if (subdir && strcmp(subdir,""))
  85. {
  86. tryPath += subdir;
  87. tryPath += "/";
  88. }
  89. tryPath += file;
  90. if(cmSystemTools::FileExists(tryPath.c_str()))
  91. {
  92. *fullPath = cmSystemTools::CollapseFullPath(tryPath.c_str());
  93. return true;
  94. }
  95. tryPath += cmSystemTools::GetExecutableExtension();
  96. if(cmSystemTools::FileExists(tryPath.c_str()))
  97. {
  98. *fullPath = cmSystemTools::CollapseFullPath(tryPath.c_str());
  99. return true;
  100. }
  101. return false;
  102. }
  103. // get the next number in a string with numbers separated by ,
  104. // pos is the start of the search and pos2 is the end of the search
  105. // pos becomes pos2 after a call to GetNextNumber.
  106. // -1 is returned at the end of the list.
  107. inline int GetNextNumber(std::string const& in,
  108. int& val,
  109. std::string::size_type& pos,
  110. std::string::size_type& pos2)
  111. {
  112. pos2 = in.find(',', pos);
  113. if(pos2 != in.npos)
  114. {
  115. if(pos2-pos == 0)
  116. {
  117. val = -1;
  118. }
  119. else
  120. {
  121. val = atoi(in.substr(pos, pos2-pos).c_str());
  122. }
  123. pos = pos2+1;
  124. return 1;
  125. }
  126. else
  127. {
  128. if(in.size()-pos == 0)
  129. {
  130. val = -1;
  131. }
  132. else
  133. {
  134. val = atoi(in.substr(pos, in.size()-pos).c_str());
  135. }
  136. return 0;
  137. }
  138. }
  139. // get the next number in a string with numbers separated by ,
  140. // pos is the start of the search and pos2 is the end of the search
  141. // pos becomes pos2 after a call to GetNextNumber.
  142. // -1 is returned at the end of the list.
  143. inline int GetNextRealNumber(std::string const& in,
  144. double& val,
  145. std::string::size_type& pos,
  146. std::string::size_type& pos2)
  147. {
  148. pos2 = in.find(',', pos);
  149. if(pos2 != in.npos)
  150. {
  151. if(pos2-pos == 0)
  152. {
  153. val = -1;
  154. }
  155. else
  156. {
  157. val = atof(in.substr(pos, pos2-pos).c_str());
  158. }
  159. pos = pos2+1;
  160. return 1;
  161. }
  162. else
  163. {
  164. if(in.size()-pos == 0)
  165. {
  166. val = -1;
  167. }
  168. else
  169. {
  170. val = atof(in.substr(pos, in.size()-pos).c_str());
  171. }
  172. return 0;
  173. }
  174. }
  175. //----------------------------------------------------------------------
  176. cmCTestTestHandler::cmCTestTestHandler()
  177. {
  178. m_Verbose = false;
  179. m_CTest = 0;
  180. m_UseUnion = false;
  181. m_UseIncludeRegExp = false;
  182. m_UseExcludeRegExp = false;
  183. m_UseExcludeRegExpFirst = false;
  184. m_CustomMaximumPassedTestOutputSize = 1 * 1024;
  185. m_CustomMaximumFailedTestOutputSize = 300 * 1024;
  186. }
  187. //----------------------------------------------------------------------
  188. void cmCTestTestHandler::PopulateCustomVectors(cmMakefile *mf)
  189. {
  190. cmCTest::PopulateCustomVector(mf, "CTEST_CUSTOM_PRE_TEST",
  191. m_CustomPreTest);
  192. cmCTest::PopulateCustomVector(mf, "CTEST_CUSTOM_POST_TEST",
  193. m_CustomPostTest);
  194. cmCTest::PopulateCustomVector(mf, "CTEST_CUSTOM_PRE_MEMCHECK",
  195. m_CustomPreMemCheck);
  196. cmCTest::PopulateCustomVector(mf, "CTEST_CUSTOM_POST_MEMCHECK",
  197. m_CustomPostMemCheck);
  198. cmCTest::PopulateCustomVector(mf,
  199. "CTEST_CUSTOM_TESTS_IGNORE",
  200. m_CustomTestsIgnore);
  201. cmCTest::PopulateCustomVector(mf,
  202. "CTEST_CUSTOM_MEMCHECK_IGNORE",
  203. m_CustomMemCheckIgnore);
  204. cmCTest::PopulateCustomInteger(mf,
  205. "CTEST_CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE",
  206. m_CustomMaximumPassedTestOutputSize);
  207. cmCTest::PopulateCustomInteger(mf,
  208. "CTEST_CUSTOM_MAXIMUM_FAILED_TEST_OUTPUT_SIZE",
  209. m_CustomMaximumFailedTestOutputSize);
  210. }
  211. //----------------------------------------------------------------------
  212. //clearly it would be nice if this were broken up into a few smaller
  213. //functions and commented...
  214. int cmCTestTestHandler::TestDirectory(cmCTest *ctest_inst, bool memcheck)
  215. {
  216. m_CTest = ctest_inst;
  217. m_TestResults.clear();
  218. std::cout << (memcheck ? "Memory check" : "Test") << " project" << std::endl;
  219. if ( memcheck )
  220. {
  221. if ( !this->InitializeMemoryChecking() )
  222. {
  223. return 1;
  224. }
  225. }
  226. if ( memcheck )
  227. {
  228. if ( !this->ExecuteCommands(m_CustomPreMemCheck) )
  229. {
  230. std::cerr << "Problem executing pre-memcheck command(s)." << std::endl;
  231. return 1;
  232. }
  233. }
  234. else
  235. {
  236. if ( !this->ExecuteCommands(m_CustomPreTest) )
  237. {
  238. std::cerr << "Problem executing pre-test command(s)." << std::endl;
  239. return 1;
  240. }
  241. }
  242. std::vector<cmStdString> passed;
  243. std::vector<cmStdString> failed;
  244. int total;
  245. this->ProcessDirectory(passed, failed, memcheck);
  246. total = int(passed.size()) + int(failed.size());
  247. if (total == 0)
  248. {
  249. if ( !m_CTest->GetShowOnly() )
  250. {
  251. std::cerr << "No tests were found!!!\n";
  252. }
  253. }
  254. else
  255. {
  256. if (m_Verbose && passed.size() &&
  257. (m_UseIncludeRegExp || m_UseExcludeRegExp))
  258. {
  259. std::cerr << "\nThe following tests passed:\n";
  260. for(std::vector<cmStdString>::iterator j = passed.begin();
  261. j != passed.end(); ++j)
  262. {
  263. std::cerr << "\t" << *j << "\n";
  264. }
  265. }
  266. float percent = float(passed.size()) * 100.0f / total;
  267. if ( failed.size() > 0 && percent > 99)
  268. {
  269. percent = 99;
  270. }
  271. fprintf(stderr,"\n%.0f%% tests passed, %i tests failed out of %i\n",
  272. percent, int(failed.size()), total);
  273. if (failed.size())
  274. {
  275. cmGeneratedFileStream ofs;
  276. std::cerr << "\nThe following tests FAILED:\n";
  277. m_CTest->OpenOutputFile("Temporary", "LastTestsFailed.log", ofs);
  278. std::vector<cmCTestTestHandler::cmCTestTestResult>::iterator ftit;
  279. for(ftit = m_TestResults.begin();
  280. ftit != m_TestResults.end(); ++ftit)
  281. {
  282. if ( ftit->m_Status != cmCTestTestHandler::COMPLETED )
  283. {
  284. ofs << ftit->m_TestCount << ":" << ftit->m_Name << std::endl;
  285. fprintf(stderr, "\t%3d - %s (%s)\n", ftit->m_TestCount, ftit->m_Name.c_str(),
  286. this->GetTestStatus(ftit->m_Status));
  287. }
  288. }
  289. }
  290. }
  291. if ( m_CTest->GetProduceXML() )
  292. {
  293. cmGeneratedFileStream xmlfile;
  294. if( !m_CTest->OpenOutputFile(m_CTest->GetCurrentTag(),
  295. (memcheck ? "DynamicAnalysis.xml" : "Test.xml"), xmlfile, true) )
  296. {
  297. std::cerr << "Cannot create " << (memcheck ? "memory check" : "testing")
  298. << " XML file" << std::endl;
  299. return 1;
  300. }
  301. if ( memcheck )
  302. {
  303. this->GenerateDartMemCheckOutput(xmlfile);
  304. }
  305. else
  306. {
  307. this->GenerateDartTestOutput(xmlfile);
  308. }
  309. }
  310. if ( memcheck )
  311. {
  312. if ( !this->ExecuteCommands(m_CustomPostMemCheck) )
  313. {
  314. std::cerr << "Problem executing post-memcheck command(s)." << std::endl;
  315. return 1;
  316. }
  317. }
  318. else
  319. {
  320. if ( !this->ExecuteCommands(m_CustomPostTest) )
  321. {
  322. std::cerr << "Problem executing post-test command(s)." << std::endl;
  323. return 1;
  324. }
  325. }
  326. return int(failed.size());
  327. }
  328. void cmCTestTestHandler::ProcessDirectory(std::vector<cmStdString> &passed,
  329. std::vector<cmStdString> &failed,
  330. bool memcheck)
  331. {
  332. std::string current_dir = cmSystemTools::GetCurrentWorkingDirectory();
  333. cmsys::RegularExpression dartStuff("(<DartMeasurement.*/DartMeasurement[a-zA-Z]*>)");
  334. tm_ListOfTests testlist;
  335. this->GetListOfTests(&testlist, memcheck);
  336. tm_ListOfTests::size_type tmsize = testlist.size();
  337. cmGeneratedFileStream ofs;
  338. cmGeneratedFileStream *olog = 0;
  339. if ( !m_CTest->GetShowOnly() && tmsize > 0 &&
  340. m_CTest->OpenOutputFile("Temporary",
  341. (memcheck?"LastMemCheck.log":"LastTest.log"), ofs) )
  342. {
  343. olog = &ofs;
  344. }
  345. m_StartTest = m_CTest->CurrentTime();
  346. double elapsed_time_start = cmSystemTools::GetTime();
  347. if ( olog )
  348. {
  349. *olog << "Start testing: " << m_StartTest << std::endl
  350. << "----------------------------------------------------------"
  351. << std::endl;
  352. }
  353. // how many tests are in based on RegExp?
  354. int inREcnt = 0;
  355. tm_ListOfTests::iterator it;
  356. for ( it = testlist.begin(); it != testlist.end(); it ++ )
  357. {
  358. if (it->m_IsInBasedOnREOptions)
  359. {
  360. inREcnt ++;
  361. }
  362. }
  363. // expand the test list based on the union flag
  364. if (m_UseUnion)
  365. {
  366. this->ExpandTestsToRunInformation((int)tmsize);
  367. }
  368. else
  369. {
  370. this->ExpandTestsToRunInformation(inREcnt);
  371. }
  372. int cnt = 0;
  373. inREcnt = 0;
  374. std::string last_directory = "";
  375. for ( it = testlist.begin(); it != testlist.end(); it ++ )
  376. {
  377. cnt ++;
  378. if (it->m_IsInBasedOnREOptions)
  379. {
  380. inREcnt++;
  381. }
  382. const std::string& testname = it->m_Name;
  383. tm_VectorOfListFileArgs& args = it->m_Args;
  384. cmCTestTestResult cres;
  385. cres.m_Status = cmCTestTestHandler::NOT_RUN;
  386. cres.m_TestCount = cnt;
  387. if (!(last_directory == it->m_Directory))
  388. {
  389. if ( m_Verbose )
  390. {
  391. std::cerr << "Changing directory into "
  392. << it->m_Directory.c_str() << "\n";
  393. }
  394. last_directory = it->m_Directory;
  395. cmSystemTools::ChangeDirectory(it->m_Directory.c_str());
  396. }
  397. cres.m_Name = testname;
  398. cres.m_Path = it->m_Directory.c_str();
  399. if (m_UseUnion)
  400. {
  401. // if it is not in the list and not in the regexp then skip
  402. if ((m_TestsToRun.size() &&
  403. std::find(m_TestsToRun.begin(), m_TestsToRun.end(), cnt)
  404. == m_TestsToRun.end()) && !it->m_IsInBasedOnREOptions)
  405. {
  406. continue;
  407. }
  408. }
  409. else
  410. {
  411. // is this test in the list of tests to run? If not then skip it
  412. if ((m_TestsToRun.size() &&
  413. std::find(m_TestsToRun.begin(), m_TestsToRun.end(), inREcnt)
  414. == m_TestsToRun.end()) || !it->m_IsInBasedOnREOptions)
  415. {
  416. continue;
  417. }
  418. }
  419. std::cerr.width(3);
  420. std::cerr << cnt << "/";
  421. std::cerr.width(3);
  422. std::cerr << tmsize << " Testing ";
  423. std::string outname = testname;
  424. outname.resize(30, ' ');
  425. if ( m_CTest->GetShowOnly() )
  426. {
  427. std::cerr << outname.c_str() << "\n";
  428. }
  429. else
  430. {
  431. std::cerr << outname.c_str();
  432. std::cerr.flush();
  433. }
  434. //std::cerr << "Testing " << args[0] << " ... ";
  435. // find the test executable
  436. std::string actualCommand = this->FindTheExecutable(args[1].Value.c_str());
  437. std::string testCommand = cmSystemTools::ConvertToOutputPath(actualCommand.c_str());
  438. std::string memcheckcommand = "";
  439. // continue if we did not find the executable
  440. if (testCommand == "")
  441. {
  442. std::cerr << "Unable to find executable: " <<
  443. args[1].Value.c_str() << "\n";
  444. if ( !m_CTest->GetShowOnly() )
  445. {
  446. cres.m_FullCommandLine = actualCommand;
  447. m_TestResults.push_back( cres );
  448. failed.push_back(testname);
  449. continue;
  450. }
  451. }
  452. // add the arguments
  453. tm_VectorOfListFileArgs::const_iterator j = args.begin();
  454. ++j;
  455. ++j;
  456. std::vector<const char*> arguments;
  457. if ( memcheck )
  458. {
  459. std::vector<cmStdString>::size_type pp;
  460. arguments.push_back(m_MemoryTester.c_str());
  461. memcheckcommand = m_MemoryTester;
  462. for ( pp = 0; pp < m_MemoryTesterOptionsParsed.size(); pp ++ )
  463. {
  464. arguments.push_back(m_MemoryTesterOptionsParsed[pp].c_str());
  465. memcheckcommand += " ";
  466. memcheckcommand += cmSystemTools::EscapeSpaces(m_MemoryTesterOptionsParsed[pp].c_str());
  467. }
  468. }
  469. arguments.push_back(actualCommand.c_str());
  470. for(;j != args.end(); ++j)
  471. {
  472. testCommand += " ";
  473. testCommand += cmSystemTools::EscapeSpaces(j->Value.c_str());
  474. arguments.push_back(j->Value.c_str());
  475. }
  476. arguments.push_back(0);
  477. /**
  478. * Run an executable command and put the stdout in output.
  479. */
  480. std::string output;
  481. int retVal = 0;
  482. if ( m_Verbose )
  483. {
  484. std::cout << std::endl << (memcheck?"MemCheck":"Test") << " command: " << testCommand << std::endl;
  485. if ( memcheck )
  486. {
  487. std::cout << "Memory check command: " << memcheckcommand << std::endl;
  488. }
  489. }
  490. if ( olog )
  491. {
  492. *olog << cnt << "/" << tmsize
  493. << " Test: " << testname.c_str() << std::endl;
  494. *olog << "Command: ";
  495. std::vector<cmStdString>::size_type ll;
  496. for ( ll = 0; ll < arguments.size()-1; ll ++ )
  497. {
  498. *olog << "\"" << arguments[ll] << "\" ";
  499. }
  500. *olog
  501. << std::endl
  502. << "Directory: " << it->m_Directory << std::endl
  503. << "\"" << testname.c_str() << "\" start time: "
  504. << m_CTest->CurrentTime() << std::endl
  505. << "Output:" << std::endl
  506. << "----------------------------------------------------------"
  507. << std::endl;
  508. }
  509. int res = 0;
  510. double clock_start, clock_finish;
  511. clock_start = cmSystemTools::GetTime();
  512. if ( !m_CTest->GetShowOnly() )
  513. {
  514. res = m_CTest->RunTest(arguments, &output, &retVal, olog);
  515. }
  516. clock_finish = cmSystemTools::GetTime();
  517. if ( olog )
  518. {
  519. double ttime = clock_finish - clock_start;
  520. int hours = static_cast<int>(ttime / (60 * 60));
  521. int minutes = static_cast<int>(ttime / 60) % 60;
  522. int seconds = static_cast<int>(ttime) % 60;
  523. char buffer[100];
  524. sprintf(buffer, "%02d:%02d:%02d", hours, minutes, seconds);
  525. *olog
  526. << "----------------------------------------------------------"
  527. << std::endl
  528. << "\"" << testname.c_str() << "\" end time: "
  529. << m_CTest->CurrentTime() << std::endl
  530. << "\"" << testname.c_str() << "\" time elapsed: "
  531. << buffer << std::endl
  532. << "----------------------------------------------------------"
  533. << std::endl << std::endl;
  534. }
  535. cres.m_ExecutionTime = (double)(clock_finish - clock_start);
  536. cres.m_FullCommandLine = testCommand;
  537. if ( !m_CTest->GetShowOnly() )
  538. {
  539. if (res == cmsysProcess_State_Exited && retVal == 0)
  540. {
  541. std::cerr << " Passed\n";
  542. passed.push_back(testname);
  543. cres.m_Status = cmCTestTestHandler::COMPLETED;
  544. }
  545. else
  546. {
  547. cres.m_Status = cmCTestTestHandler::FAILED;
  548. if ( res == cmsysProcess_State_Expired )
  549. {
  550. std::cerr << "***Timeout\n";
  551. cres.m_Status = cmCTestTestHandler::TIMEOUT;
  552. }
  553. else if ( res == cmsysProcess_State_Exception )
  554. {
  555. std::cerr << "***Exception: ";
  556. switch ( retVal )
  557. {
  558. case cmsysProcess_Exception_Fault:
  559. std::cerr << "SegFault";
  560. cres.m_Status = cmCTestTestHandler::SEGFAULT;
  561. break;
  562. case cmsysProcess_Exception_Illegal:
  563. std::cerr << "Illegal";
  564. cres.m_Status = cmCTestTestHandler::ILLEGAL;
  565. break;
  566. case cmsysProcess_Exception_Interrupt:
  567. std::cerr << "Interrupt";
  568. cres.m_Status = cmCTestTestHandler::INTERRUPT;
  569. break;
  570. case cmsysProcess_Exception_Numerical:
  571. std::cerr << "Numerical";
  572. cres.m_Status = cmCTestTestHandler::NUMERICAL;
  573. break;
  574. default:
  575. std::cerr << "Other";
  576. cres.m_Status = cmCTestTestHandler::OTHER_FAULT;
  577. }
  578. std::cerr << "\n";
  579. }
  580. else if ( res == cmsysProcess_State_Error )
  581. {
  582. std::cerr << "***Bad command " << res << "\n";
  583. cres.m_Status = cmCTestTestHandler::BAD_COMMAND;
  584. }
  585. else
  586. {
  587. std::cerr << "***Failed\n";
  588. }
  589. failed.push_back(testname);
  590. }
  591. if (output != "")
  592. {
  593. if (dartStuff.find(output.c_str()))
  594. {
  595. std::string dartString = dartStuff.match(1);
  596. cmSystemTools::ReplaceString(output, dartString.c_str(),"");
  597. cres.m_RegressionImages = this->GenerateRegressionImages(dartString);
  598. }
  599. }
  600. }
  601. if ( cres.m_Status == cmCTestTestHandler::COMPLETED )
  602. {
  603. this->CleanTestOutput(output, static_cast<size_t>(m_CustomMaximumPassedTestOutputSize));
  604. }
  605. else
  606. {
  607. this->CleanTestOutput(output, static_cast<size_t>(m_CustomMaximumFailedTestOutputSize));
  608. }
  609. cres.m_Output = output;
  610. cres.m_ReturnValue = retVal;
  611. cres.m_CompletionStatus = "Completed";
  612. m_TestResults.push_back( cres );
  613. }
  614. m_EndTest = m_CTest->CurrentTime();
  615. m_ElapsedTestingTime = cmSystemTools::GetTime() - elapsed_time_start;
  616. if ( olog )
  617. {
  618. *olog << "End testing: " << m_EndTest << std::endl;
  619. }
  620. cmSystemTools::ChangeDirectory(current_dir.c_str());
  621. }
  622. void cmCTestTestHandler::GenerateDartMemCheckOutput(std::ostream& os)
  623. {
  624. if ( !m_CTest->GetProduceXML() )
  625. {
  626. return;
  627. }
  628. m_CTest->StartXML(os);
  629. os << "<DynamicAnalysis Checker=\"";
  630. switch ( m_MemoryTesterStyle )
  631. {
  632. case cmCTestTestHandler::VALGRIND:
  633. os << "Valgrind";
  634. break;
  635. case cmCTestTestHandler::PURIFY:
  636. os << "Purify";
  637. break;
  638. case cmCTestTestHandler::BOUNDS_CHECKER:
  639. os << "BoundsChecker";
  640. break;
  641. default:
  642. os << "Unknown";
  643. }
  644. os << "\">" << std::endl;
  645. os << "\t<StartDateTime>" << m_StartTest << "</StartDateTime>\n"
  646. << "\t<TestList>\n";
  647. tm_TestResultsVector::size_type cc;
  648. for ( cc = 0; cc < m_TestResults.size(); cc ++ )
  649. {
  650. cmCTestTestResult *result = &m_TestResults[cc];
  651. std::string testPath = result->m_Path + "/" + result->m_Name;
  652. os << "\t\t<Test>" << cmCTest::MakeXMLSafe(
  653. m_CTest->GetShortPathToFile(testPath.c_str()))
  654. << "</Test>" << std::endl;
  655. }
  656. os << "\t</TestList>\n";
  657. std::cout << "-- Processing memory checking output: ";
  658. unsigned int total = m_TestResults.size();
  659. unsigned int step = total / 10;
  660. unsigned int current = 0;
  661. for ( cc = 0; cc < m_TestResults.size(); cc ++ )
  662. {
  663. cmCTestTestResult *result = &m_TestResults[cc];
  664. std::string memcheckstr;
  665. int memcheckresults[cmCTestTestHandler::NO_MEMORY_FAULT];
  666. int kk;
  667. bool res = this->ProcessMemCheckOutput(result->m_Output, memcheckstr, memcheckresults);
  668. if ( res && result->m_Status == cmCTestTestHandler::COMPLETED )
  669. {
  670. continue;
  671. }
  672. os << "\t<Test Status=\"";
  673. if ( result->m_Status == cmCTestTestHandler::COMPLETED )
  674. {
  675. os << "passed";
  676. }
  677. else if ( result->m_Status == cmCTestTestHandler::NOT_RUN )
  678. {
  679. os << "notrun";
  680. }
  681. else
  682. {
  683. os << "failed";
  684. }
  685. std::string testPath = result->m_Path + "/" + result->m_Name;
  686. os << "\">\n"
  687. << "\t\t<Name>" << cmCTest::MakeXMLSafe(result->m_Name) << "</Name>\n"
  688. << "\t\t<Path>" << cmCTest::MakeXMLSafe(
  689. m_CTest->GetShortPathToFile(result->m_Path.c_str())) << "</Path>\n"
  690. << "\t\t<FullName>" << cmCTest::MakeXMLSafe(
  691. m_CTest->GetShortPathToFile(testPath.c_str())) << "</FullName>\n"
  692. << "\t\t<FullCommandLine>"
  693. << cmCTest::MakeXMLSafe(result->m_FullCommandLine)
  694. << "</FullCommandLine>\n"
  695. << "\t\t<Results>" << std::endl;
  696. for ( kk = 0; cmCTestMemCheckResultLongStrings[kk]; kk ++ )
  697. {
  698. if ( memcheckresults[kk] )
  699. {
  700. os << "\t\t\t<Defect type=\"" << cmCTestMemCheckResultLongStrings[kk] << "\">"
  701. << memcheckresults[kk]
  702. << "</Defect>" << std::endl;
  703. }
  704. m_MemoryTesterGlobalResults[kk] += memcheckresults[kk];
  705. }
  706. os
  707. << "\t\t</Results>\n"
  708. << "\t<Log>\n" << memcheckstr << std::endl
  709. << "\t</Log>\n"
  710. << "\t</Test>" << std::endl;
  711. if ( current < cc )
  712. {
  713. std::cout << "#";
  714. std::cout.flush();
  715. current += step;
  716. }
  717. }
  718. std::cout << std::endl;
  719. std::cerr << "Memory checking results:" << std::endl;
  720. os << "\t<DefectList>" << std::endl;
  721. for ( cc = 0; cmCTestMemCheckResultStrings[cc]; cc ++ )
  722. {
  723. if ( m_MemoryTesterGlobalResults[cc] )
  724. {
  725. std::cerr.width(35);
  726. std::cerr << cmCTestMemCheckResultLongStrings[cc] << " - "
  727. << m_MemoryTesterGlobalResults[cc] << std::endl;
  728. os << "\t\t<Defect Type=\"" << cmCTestMemCheckResultLongStrings[cc] << "\"/>" << std::endl;
  729. }
  730. }
  731. os << "\t</DefectList>" << std::endl;
  732. os << "\t<EndDateTime>" << m_EndTest << "</EndDateTime>" << std::endl;
  733. os << "<ElapsedMinutes>"
  734. << static_cast<int>(m_ElapsedTestingTime/6)/10.0
  735. << "</ElapsedMinutes>\n";
  736. os << "</DynamicAnalysis>" << std::endl;
  737. m_CTest->EndXML(os);
  738. }
  739. void cmCTestTestHandler::GenerateDartTestOutput(std::ostream& os)
  740. {
  741. if ( !m_CTest->GetProduceXML() )
  742. {
  743. return;
  744. }
  745. m_CTest->StartXML(os);
  746. os << "<Testing>\n"
  747. << "\t<StartDateTime>" << m_StartTest << "</StartDateTime>\n"
  748. << "\t<TestList>\n";
  749. tm_TestResultsVector::size_type cc;
  750. for ( cc = 0; cc < m_TestResults.size(); cc ++ )
  751. {
  752. cmCTestTestResult *result = &m_TestResults[cc];
  753. std::string testPath = result->m_Path + "/" + result->m_Name;
  754. os << "\t\t<Test>" << cmCTest::MakeXMLSafe(
  755. m_CTest->GetShortPathToFile(testPath.c_str()))
  756. << "</Test>" << std::endl;
  757. }
  758. os << "\t</TestList>\n";
  759. for ( cc = 0; cc < m_TestResults.size(); cc ++ )
  760. {
  761. cmCTestTestResult *result = &m_TestResults[cc];
  762. os << "\t<Test Status=\"";
  763. if ( result->m_Status == cmCTestTestHandler::COMPLETED )
  764. {
  765. os << "passed";
  766. }
  767. else if ( result->m_Status == cmCTestTestHandler::NOT_RUN )
  768. {
  769. os << "notrun";
  770. }
  771. else
  772. {
  773. os << "failed";
  774. }
  775. std::string testPath = result->m_Path + "/" + result->m_Name;
  776. os << "\">\n"
  777. << "\t\t<Name>" << cmCTest::MakeXMLSafe(result->m_Name) << "</Name>\n"
  778. << "\t\t<Path>" << cmCTest::MakeXMLSafe(
  779. m_CTest->GetShortPathToFile(result->m_Path.c_str())) << "</Path>\n"
  780. << "\t\t<FullName>" << cmCTest::MakeXMLSafe(
  781. m_CTest->GetShortPathToFile(testPath.c_str())) << "</FullName>\n"
  782. << "\t\t<FullCommandLine>"
  783. << cmCTest::MakeXMLSafe(result->m_FullCommandLine)
  784. << "</FullCommandLine>\n"
  785. << "\t\t<Results>" << std::endl;
  786. if ( result->m_Status != cmCTestTestHandler::NOT_RUN )
  787. {
  788. if ( result->m_Status != cmCTestTestHandler::COMPLETED || result->m_ReturnValue )
  789. {
  790. os << "\t\t\t<NamedMeasurement type=\"text/string\" name=\"Exit Code\"><Value>"
  791. << this->GetTestStatus(result->m_Status) << "</Value></NamedMeasurement>\n"
  792. << "\t\t\t<NamedMeasurement type=\"text/string\" name=\"Exit Value\"><Value>"
  793. << result->m_ReturnValue << "</Value></NamedMeasurement>" << std::endl;
  794. }
  795. os << result->m_RegressionImages;
  796. os << "\t\t\t<NamedMeasurement type=\"numeric/double\" "
  797. << "name=\"Execution Time\"><Value>"
  798. << result->m_ExecutionTime << "</Value></NamedMeasurement>\n";
  799. os
  800. << "\t\t\t<NamedMeasurement type=\"text/string\" "
  801. << "name=\"Completion Status\"><Value>"
  802. << result->m_CompletionStatus << "</Value></NamedMeasurement>\n";
  803. }
  804. os
  805. << "\t\t\t<Measurement>\n"
  806. << "\t\t\t\t<Value>";
  807. os << cmCTest::MakeXMLSafe(result->m_Output);
  808. os
  809. << "</Value>\n"
  810. << "\t\t\t</Measurement>\n"
  811. << "\t\t</Results>\n"
  812. << "\t</Test>" << std::endl;
  813. }
  814. os << "\t<EndDateTime>" << m_EndTest << "</EndDateTime>\n"
  815. << "<ElapsedMinutes>"
  816. << static_cast<int>(m_ElapsedTestingTime/6)/10.0
  817. << "</ElapsedMinutes>"
  818. << "</Testing>" << std::endl;
  819. m_CTest->EndXML(os);
  820. }
  821. bool cmCTestTestHandler::InitializeMemoryChecking()
  822. {
  823. // Setup the command
  824. if ( cmSystemTools::FileExists(m_CTest->GetDartConfiguration("MemoryCheckCommand").c_str()) )
  825. {
  826. m_MemoryTester
  827. = cmSystemTools::ConvertToOutputPath(m_CTest->GetDartConfiguration("MemoryCheckCommand").c_str());
  828. }
  829. else if ( cmSystemTools::FileExists(m_CTest->GetDartConfiguration("PurifyCommand").c_str()) )
  830. {
  831. m_MemoryTester
  832. = cmSystemTools::ConvertToOutputPath(m_CTest->GetDartConfiguration("PurifyCommand").c_str());
  833. }
  834. else if ( cmSystemTools::FileExists(m_CTest->GetDartConfiguration("ValgrindCommand").c_str()) )
  835. {
  836. m_MemoryTester
  837. = cmSystemTools::ConvertToOutputPath(m_CTest->GetDartConfiguration("ValgrindCommand").c_str());
  838. }
  839. else
  840. {
  841. std::cerr << "Memory checker (MemoryCheckCommand) not set, or cannot find the specified program."
  842. << std::endl;
  843. return false;
  844. }
  845. if ( m_MemoryTester[0] == '\"' && m_MemoryTester[m_MemoryTester.size()-1] == '\"' )
  846. {
  847. m_MemoryTester = m_MemoryTester.substr(1, m_MemoryTester.size()-2);
  848. }
  849. // Setup the options
  850. if ( m_CTest->GetDartConfiguration("MemoryCheckCommandOptions").size() )
  851. {
  852. m_MemoryTesterOptions = m_CTest->GetDartConfiguration("MemoryCheckCommandOptions");
  853. }
  854. else if ( m_CTest->GetDartConfiguration("ValgrindCommandOptions").size() )
  855. {
  856. m_MemoryTesterOptions = m_CTest->GetDartConfiguration("ValgrindCommandOptions");
  857. }
  858. m_MemoryTesterOutputFile = m_CTest->GetToplevelPath() + "/Testing/Temporary/MemoryChecker.log";
  859. m_MemoryTesterOutputFile = cmSystemTools::EscapeSpaces(m_MemoryTesterOutputFile.c_str());
  860. if ( m_MemoryTester.find("valgrind") != std::string::npos )
  861. {
  862. m_MemoryTesterStyle = cmCTestTestHandler::VALGRIND;
  863. if ( !m_MemoryTesterOptions.size() )
  864. {
  865. m_MemoryTesterOptions = "-q --skin=memcheck --leak-check=yes --show-reachable=yes --workaround-gcc296-bugs=yes --num-callers=100";
  866. }
  867. if ( m_CTest->GetDartConfiguration("MemoryCheckSuppressionFile").size() )
  868. {
  869. if ( !cmSystemTools::FileExists(m_CTest->GetDartConfiguration("MemoryCheckSuppressionFile").c_str()) )
  870. {
  871. std::cerr << "Cannot find memory checker suppression file: "
  872. << m_CTest->GetDartConfiguration("MemoryCheckSuppressionFile").c_str() << std::endl;
  873. return false;
  874. }
  875. m_MemoryTesterOptions += " --suppressions=" + cmSystemTools::EscapeSpaces(m_CTest->GetDartConfiguration("MemoryCheckSuppressionFile").c_str()) + "";
  876. }
  877. }
  878. else if ( m_MemoryTester.find("purify") != std::string::npos )
  879. {
  880. m_MemoryTesterStyle = cmCTestTestHandler::PURIFY;
  881. #ifdef _WIN32
  882. m_MemoryTesterOptions += " /SAVETEXTDATA=" + m_MemoryTesterOutputFile;
  883. #else
  884. m_MemoryTesterOptions += " -log-file=" + m_MemoryTesterOutputFile;
  885. #endif
  886. }
  887. else if ( m_MemoryTester.find("boundschecker") != std::string::npos )
  888. {
  889. m_MemoryTesterStyle = cmCTestTestHandler::BOUNDS_CHECKER;
  890. std::cerr << "Bounds checker not yet implemented" << std::endl;
  891. return false;
  892. }
  893. else
  894. {
  895. std::cerr << "Do not understand memory checker: " << m_MemoryTester.c_str() << std::endl;
  896. return false;
  897. }
  898. m_MemoryTesterOptionsParsed = cmSystemTools::ParseArguments(m_MemoryTesterOptions.c_str());
  899. std::vector<cmStdString>::size_type cc;
  900. for ( cc = 0; cmCTestMemCheckResultStrings[cc]; cc ++ )
  901. {
  902. m_MemoryTesterGlobalResults[cc] = 0;
  903. }
  904. return true;
  905. }
  906. int cmCTestTestHandler::ExecuteCommands(std::vector<cmStdString>& vec)
  907. {
  908. std::vector<cmStdString>::iterator it;
  909. for ( it = vec.begin(); it != vec.end(); ++it )
  910. {
  911. int retVal = 0;
  912. if ( m_Verbose )
  913. {
  914. std::cout << "Run command: " << *it << std::endl;
  915. }
  916. if ( !cmSystemTools::RunSingleCommand(it->c_str(), 0, &retVal, 0, true /*m_Verbose*/) ||
  917. retVal != 0 )
  918. {
  919. std::cerr << "Problem running command: " << *it << std::endl;
  920. return 0;
  921. }
  922. }
  923. return 1;
  924. }
  925. std::string cmCTestTestHandler::FindTheExecutable(const char *exe)
  926. {
  927. std::string fullPath = "";
  928. std::string dir;
  929. std::string file;
  930. cmSystemTools::SplitProgramPath(exe, dir, file);
  931. if(m_CTest->GetConfigType() != "" &&
  932. ::TryExecutable(dir.c_str(), file.c_str(), &fullPath,
  933. m_CTest->GetConfigType().c_str()))
  934. {
  935. return fullPath;
  936. }
  937. if (::TryExecutable(dir.c_str(),file.c_str(),&fullPath,"."))
  938. {
  939. return fullPath;
  940. }
  941. if (::TryExecutable(dir.c_str(),file.c_str(),&fullPath,""))
  942. {
  943. return fullPath;
  944. }
  945. if ( m_CTest->GetConfigType() == "" )
  946. {
  947. // No config type, so try to guess it
  948. if (::TryExecutable(dir.c_str(),file.c_str(),&fullPath,"Release"))
  949. {
  950. return fullPath;
  951. }
  952. if (::TryExecutable(dir.c_str(),file.c_str(),&fullPath,"Debug"))
  953. {
  954. return fullPath;
  955. }
  956. if (::TryExecutable(dir.c_str(),file.c_str(),&fullPath,"MinSizeRel"))
  957. {
  958. return fullPath;
  959. }
  960. if (::TryExecutable(dir.c_str(),file.c_str(),&fullPath,"RelWithDebInfo"))
  961. {
  962. return fullPath;
  963. }
  964. }
  965. // if everything else failed, check the users path
  966. if (dir != "")
  967. {
  968. std::string path = cmSystemTools::FindProgram(file.c_str());
  969. if (path != "")
  970. {
  971. return path;
  972. }
  973. }
  974. if ( m_CTest->GetConfigType() != "" )
  975. {
  976. dir += "/";
  977. dir += m_CTest->GetConfigType();
  978. dir += "/";
  979. dir += file;
  980. cmSystemTools::Error("config type specified on the command line, but test executable not found.",
  981. dir.c_str());
  982. return "";
  983. }
  984. return fullPath;
  985. }
  986. void cmCTestTestHandler::GetListOfTests(tm_ListOfTests* testlist,
  987. bool memcheck)
  988. {
  989. // does the DartTestfile.txt exist ?
  990. if(!cmSystemTools::FileExists("DartTestfile.txt"))
  991. {
  992. return;
  993. }
  994. // parse the file
  995. std::ifstream fin("DartTestfile.txt");
  996. if(!fin)
  997. {
  998. return;
  999. }
  1000. cmsys::RegularExpression ireg(this->m_IncludeRegExp.c_str());
  1001. cmsys::RegularExpression ereg(this->m_ExcludeRegExp.c_str());
  1002. cmListFileCache cache;
  1003. cmListFile* listFile = cache.GetFileCache("DartTestfile.txt", false);
  1004. for(std::vector<cmListFileFunction>::const_iterator f =
  1005. listFile->m_Functions.begin(); f != listFile->m_Functions.end(); ++f)
  1006. {
  1007. const cmListFileFunction& lff = *f;
  1008. const std::string& name = lff.m_Name;
  1009. const tm_VectorOfListFileArgs& args = lff.m_Arguments;
  1010. if (name == "SUBDIRS")
  1011. {
  1012. std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
  1013. for(tm_VectorOfListFileArgs::const_iterator j = args.begin();
  1014. j != args.end(); ++j)
  1015. {
  1016. std::string nwd = cwd + "/";
  1017. nwd += j->Value;
  1018. if (cmSystemTools::FileIsDirectory(nwd.c_str()))
  1019. {
  1020. cmSystemTools::ChangeDirectory(nwd.c_str());
  1021. this->GetListOfTests(testlist, memcheck);
  1022. }
  1023. }
  1024. // return to the original directory
  1025. cmSystemTools::ChangeDirectory(cwd.c_str());
  1026. }
  1027. if (name == "ADD_TEST")
  1028. {
  1029. const std::string& testname = args[0].Value;
  1030. if (this->m_UseExcludeRegExp &&
  1031. this->m_UseExcludeRegExpFirst &&
  1032. ereg.find(testname.c_str()))
  1033. {
  1034. continue;
  1035. }
  1036. if ( memcheck )
  1037. {
  1038. std::vector<cmStdString>::iterator it;
  1039. bool found = false;
  1040. for ( it = m_CustomMemCheckIgnore.begin();
  1041. it != m_CustomMemCheckIgnore.end(); ++ it )
  1042. {
  1043. if ( *it == testname )
  1044. {
  1045. found = true;
  1046. break;
  1047. }
  1048. }
  1049. if ( found )
  1050. {
  1051. if ( m_Verbose )
  1052. {
  1053. std::cout << "Ignore memcheck: " << *it << std::endl;
  1054. }
  1055. continue;
  1056. }
  1057. }
  1058. else
  1059. {
  1060. std::vector<cmStdString>::iterator it;
  1061. bool found = false;
  1062. for ( it = m_CustomTestsIgnore.begin();
  1063. it != m_CustomTestsIgnore.end(); ++ it )
  1064. {
  1065. if ( *it == testname )
  1066. {
  1067. found = true;
  1068. break;
  1069. }
  1070. }
  1071. if ( found )
  1072. {
  1073. if ( m_Verbose )
  1074. {
  1075. std::cout << "Ignore test: " << *it << std::endl;
  1076. }
  1077. continue;
  1078. }
  1079. }
  1080. cmCTestTestProperties test;
  1081. test.m_Name = testname;
  1082. test.m_Args = args;
  1083. test.m_Directory = cmSystemTools::GetCurrentWorkingDirectory();
  1084. test.m_IsInBasedOnREOptions = true;
  1085. if (this->m_UseIncludeRegExp && !ireg.find(testname.c_str()))
  1086. {
  1087. test.m_IsInBasedOnREOptions = false;
  1088. }
  1089. else if (this->m_UseExcludeRegExp &&
  1090. !this->m_UseExcludeRegExpFirst &&
  1091. ereg.find(testname.c_str()))
  1092. {
  1093. test.m_IsInBasedOnREOptions = false;
  1094. }
  1095. testlist->push_back(test);
  1096. }
  1097. }
  1098. }
  1099. void cmCTestTestHandler::UseIncludeRegExp()
  1100. {
  1101. this->m_UseIncludeRegExp = true;
  1102. }
  1103. void cmCTestTestHandler::UseExcludeRegExp()
  1104. {
  1105. this->m_UseExcludeRegExp = true;
  1106. this->m_UseExcludeRegExpFirst = this->m_UseIncludeRegExp ? false : true;
  1107. }
  1108. const char* cmCTestTestHandler::GetTestStatus(int status)
  1109. {
  1110. static const char statuses[][100] = {
  1111. "Not Run",
  1112. "Timeout",
  1113. "SEGFAULT",
  1114. "ILLEGAL",
  1115. "INTERRUPT",
  1116. "NUMERICAL",
  1117. "OTHER_FAULT",
  1118. "Failed",
  1119. "BAD_COMMAND",
  1120. "Completed"
  1121. };
  1122. if ( status < cmCTestTestHandler::NOT_RUN ||
  1123. status > cmCTestTestHandler::COMPLETED )
  1124. {
  1125. return "No Status";
  1126. }
  1127. return statuses[status];
  1128. }
  1129. void cmCTestTestHandler::ExpandTestsToRunInformation(int numTests)
  1130. {
  1131. if (this->TestsToRunString.empty())
  1132. {
  1133. return;
  1134. }
  1135. int start;
  1136. int end = -1;
  1137. double stride = -1;
  1138. std::string::size_type pos = 0;
  1139. std::string::size_type pos2;
  1140. // read start
  1141. if(GetNextNumber(this->TestsToRunString, start, pos, pos2))
  1142. {
  1143. // read end
  1144. if(GetNextNumber(this->TestsToRunString, end, pos, pos2))
  1145. {
  1146. // read stride
  1147. if(GetNextRealNumber(this->TestsToRunString, stride, pos, pos2))
  1148. {
  1149. int val =0;
  1150. // now read specific numbers
  1151. while(GetNextNumber(this->TestsToRunString, val, pos, pos2))
  1152. {
  1153. m_TestsToRun.push_back(val);
  1154. }
  1155. m_TestsToRun.push_back(val);
  1156. }
  1157. }
  1158. }
  1159. // if start is not specified then we assume we start at 1
  1160. if(start == -1)
  1161. {
  1162. start = 1;
  1163. }
  1164. // if end isnot specified then we assume we end with the last test
  1165. if(end == -1)
  1166. {
  1167. end = numTests;
  1168. }
  1169. // if the stride wasn't specified then it defaults to 1
  1170. if(stride == -1)
  1171. {
  1172. stride = 1;
  1173. }
  1174. // if we have a range then add it
  1175. if(end != -1 && start != -1 && stride > 0)
  1176. {
  1177. int i = 0;
  1178. while (i*stride + start <= end)
  1179. {
  1180. m_TestsToRun.push_back(static_cast<int>(i*stride+start));
  1181. ++i;
  1182. }
  1183. }
  1184. // sort the array
  1185. std::sort(m_TestsToRun.begin(), m_TestsToRun.end(), std::less<int>());
  1186. // remove duplicates
  1187. std::vector<int>::iterator new_end =
  1188. std::unique(m_TestsToRun.begin(), m_TestsToRun.end());
  1189. m_TestsToRun.erase(new_end, m_TestsToRun.end());
  1190. }
  1191. #define SPACE_REGEX "[ \t\r\n]"
  1192. std::string cmCTestTestHandler::GenerateRegressionImages(
  1193. const std::string& xml)
  1194. {
  1195. cmsys::RegularExpression twoattributes(
  1196. "<DartMeasurement"
  1197. SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\""
  1198. SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\""
  1199. SPACE_REGEX "*>([^<]*)</DartMeasurement>");
  1200. cmsys::RegularExpression threeattributes(
  1201. "<DartMeasurement"
  1202. SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\""
  1203. SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\""
  1204. SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\""
  1205. SPACE_REGEX "*>([^<]*)</DartMeasurement>");
  1206. cmsys::RegularExpression fourattributes(
  1207. "<DartMeasurement"
  1208. SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\""
  1209. SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\""
  1210. SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\""
  1211. SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\""
  1212. SPACE_REGEX "*>([^<]*)</DartMeasurement>");
  1213. cmsys::RegularExpression measurementfile(
  1214. "<DartMeasurementFile"
  1215. SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\""
  1216. SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\""
  1217. SPACE_REGEX "*>([^<]*)</DartMeasurementFile>");
  1218. cmOStringStream ostr;
  1219. bool done = false;
  1220. std::string cxml = xml;
  1221. while ( ! done )
  1222. {
  1223. if ( twoattributes.find(cxml) )
  1224. {
  1225. ostr
  1226. << "\t\t\t<NamedMeasurement"
  1227. << " " << twoattributes.match(1) << "=\"" << twoattributes.match(2) << "\""
  1228. << " " << twoattributes.match(3) << "=\"" << twoattributes.match(4) << "\""
  1229. << "><Value>" << twoattributes.match(5)
  1230. << "</Value></NamedMeasurement>"
  1231. << std::endl;
  1232. cxml.erase(twoattributes.start(), twoattributes.end() - twoattributes.start());
  1233. }
  1234. else if ( threeattributes.find(cxml) )
  1235. {
  1236. ostr
  1237. << "\t\t\t<NamedMeasurement"
  1238. << " " << threeattributes.match(1) << "=\"" << threeattributes.match(2) << "\""
  1239. << " " << threeattributes.match(3) << "=\"" << threeattributes.match(4) << "\""
  1240. << " " << threeattributes.match(5) << "=\"" << threeattributes.match(6) << "\""
  1241. << "><Value>" << threeattributes.match(7)
  1242. << "</Value></NamedMeasurement>"
  1243. << std::endl;
  1244. cxml.erase(threeattributes.start(), threeattributes.end() - threeattributes.start());
  1245. }
  1246. else if ( fourattributes.find(cxml) )
  1247. {
  1248. ostr
  1249. << "\t\t\t<NamedMeasurement"
  1250. << " " << fourattributes.match(1) << "=\"" << fourattributes.match(2) << "\""
  1251. << " " << fourattributes.match(3) << "=\"" << fourattributes.match(4) << "\""
  1252. << " " << fourattributes.match(5) << "=\"" << fourattributes.match(6) << "\""
  1253. << " " << fourattributes.match(7) << "=\"" << fourattributes.match(8) << "\""
  1254. << "><Value>" << fourattributes.match(9)
  1255. << "</Value></NamedMeasurement>"
  1256. << std::endl;
  1257. cxml.erase(fourattributes.start(), fourattributes.end() - fourattributes.start());
  1258. }
  1259. else if ( measurementfile.find(cxml) )
  1260. {
  1261. const std::string& filename =
  1262. cmCTest::CleanString(measurementfile.match(5));
  1263. if ( cmSystemTools::FileExists(filename.c_str()) )
  1264. {
  1265. long len = cmSystemTools::FileLength(filename.c_str());
  1266. if ( len == 0 )
  1267. {
  1268. std::string k1 = measurementfile.match(1);
  1269. std::string v1 = measurementfile.match(2);
  1270. std::string k2 = measurementfile.match(3);
  1271. std::string v2 = measurementfile.match(4);
  1272. if ( cmSystemTools::LowerCase(k1) == "type" )
  1273. {
  1274. v1 = "text/string";
  1275. }
  1276. if ( cmSystemTools::LowerCase(k2) == "type" )
  1277. {
  1278. v2 = "text/string";
  1279. }
  1280. ostr
  1281. << "\t\t\t<NamedMeasurement"
  1282. << " " << k1 << "=\"" << v1 << "\""
  1283. << " " << k2 << "=\"" << v2 << "\""
  1284. << " encoding=\"none\""
  1285. << "><Value>Image " << filename.c_str()
  1286. << " is empty</Value></NamedMeasurement>";
  1287. }
  1288. else
  1289. {
  1290. std::ifstream ifs(filename.c_str(), std::ios::in
  1291. #ifdef _WIN32
  1292. | std::ios::binary
  1293. #endif
  1294. );
  1295. unsigned char *file_buffer = new unsigned char [ len + 1 ];
  1296. ifs.read(reinterpret_cast<char*>(file_buffer), len);
  1297. unsigned char *encoded_buffer = new unsigned char [ static_cast<int>(len * 1.5 + 5) ];
  1298. unsigned long rlen = cmsysBase64_Encode(file_buffer, len, encoded_buffer, 1);
  1299. unsigned long cc;
  1300. ostr
  1301. << "\t\t\t<NamedMeasurement"
  1302. << " " << measurementfile.match(1) << "=\"" << measurementfile.match(2) << "\""
  1303. << " " << measurementfile.match(3) << "=\"" << measurementfile.match(4) << "\""
  1304. << " encoding=\"base64\""
  1305. << ">" << std::endl << "\t\t\t\t<Value>";
  1306. for ( cc = 0; cc < rlen; cc ++ )
  1307. {
  1308. ostr << encoded_buffer[cc];
  1309. if ( cc % 60 == 0 && cc )
  1310. {
  1311. ostr << std::endl;
  1312. }
  1313. }
  1314. ostr
  1315. << "</Value>" << std::endl << "\t\t\t</NamedMeasurement>"
  1316. << std::endl;
  1317. delete [] file_buffer;
  1318. delete [] encoded_buffer;
  1319. }
  1320. }
  1321. else
  1322. {
  1323. int idx = 4;
  1324. if ( measurementfile.match(1) == "name" )
  1325. {
  1326. idx = 2;
  1327. }
  1328. ostr
  1329. << "\t\t\t<NamedMeasurement"
  1330. << " name=\"" << measurementfile.match(idx) << "\""
  1331. << " text=\"text/string\""
  1332. << "><Value>File " << filename.c_str() << " not found</Value></NamedMeasurement>"
  1333. << std::endl;
  1334. std::cout << "File \"" << filename.c_str() << "\" not found." << std::endl;
  1335. }
  1336. cxml.erase(measurementfile.start(), measurementfile.end() - measurementfile.start());
  1337. }
  1338. else
  1339. {
  1340. done = true;
  1341. }
  1342. }
  1343. return ostr.str();
  1344. }
  1345. bool cmCTestTestHandler::ProcessMemCheckOutput(const std::string& str,
  1346. std::string& log, int* results)
  1347. {
  1348. std::string::size_type cc;
  1349. for ( cc = 0; cc < cmCTestTestHandler::NO_MEMORY_FAULT; cc ++ )
  1350. {
  1351. results[cc] = 0;
  1352. }
  1353. if ( m_MemoryTesterStyle == cmCTestTestHandler::VALGRIND )
  1354. {
  1355. return this->ProcessMemCheckValgrindOutput(str, log, results);
  1356. }
  1357. else if ( m_MemoryTesterStyle == cmCTestTestHandler::PURIFY )
  1358. {
  1359. return this->ProcessMemCheckPurifyOutput(str, log, results);
  1360. }
  1361. else if ( m_MemoryTesterStyle == cmCTestTestHandler::BOUNDS_CHECKER )
  1362. {
  1363. log.append("\nMemory checking style used was: ");
  1364. log.append("Bounds Checker");
  1365. }
  1366. else
  1367. {
  1368. log.append("\nMemory checking style used was: ");
  1369. log.append("None that I know");
  1370. log = str;
  1371. }
  1372. return true;
  1373. }
  1374. bool cmCTestTestHandler::ProcessMemCheckPurifyOutput(
  1375. const std::string&, std::string& log,
  1376. int* results)
  1377. {
  1378. if ( !cmSystemTools::FileExists(m_MemoryTesterOutputFile.c_str()) )
  1379. {
  1380. log = "Cannot find Purify output file: " + m_MemoryTesterOutputFile;
  1381. std::cerr << log.c_str() << std::endl;
  1382. return false;
  1383. }
  1384. std::ifstream ifs(m_MemoryTesterOutputFile.c_str());
  1385. if ( !ifs )
  1386. {
  1387. log = "Cannot read Purify output file: " + m_MemoryTesterOutputFile;
  1388. std::cerr << log.c_str() << std::endl;
  1389. return false;
  1390. }
  1391. cmOStringStream ostr;
  1392. log = "";
  1393. cmsys::RegularExpression pfW("^\\[[WEI]\\] ([A-Z][A-Z][A-Z][A-Z]*): ");
  1394. int defects = 0;
  1395. std::string line;
  1396. while ( cmSystemTools::GetLineFromStream(ifs, line) )
  1397. {
  1398. int failure = cmCTestTestHandler::NO_MEMORY_FAULT;
  1399. if ( pfW.find(line) )
  1400. {
  1401. int cc;
  1402. for ( cc = 0; cc < cmCTestTestHandler::NO_MEMORY_FAULT; cc ++ )
  1403. {
  1404. if ( pfW.match(1) == cmCTestMemCheckResultStrings[cc] )
  1405. {
  1406. failure = cc;
  1407. break;
  1408. }
  1409. }
  1410. if ( cc == cmCTestTestHandler::NO_MEMORY_FAULT )
  1411. {
  1412. std::cerr<< "Unknown Purify memory fault: " << pfW.match(1) << std::endl;
  1413. ostr << "*** Unknown Purify memory fault: " << pfW.match(1) << std::endl;
  1414. }
  1415. }
  1416. if ( failure != NO_MEMORY_FAULT )
  1417. {
  1418. ostr << "<b>" << cmCTestMemCheckResultStrings[failure] << "</b> ";
  1419. results[failure] ++;
  1420. defects ++;
  1421. }
  1422. ostr << cmCTest::MakeXMLSafe(line) << std::endl;
  1423. }
  1424. log = ostr.str();
  1425. if ( defects )
  1426. {
  1427. return false;
  1428. }
  1429. return true;
  1430. }
  1431. bool cmCTestTestHandler::ProcessMemCheckValgrindOutput(
  1432. const std::string& str, std::string& log,
  1433. int* results)
  1434. {
  1435. std::vector<cmStdString> lines;
  1436. cmSystemTools::Split(str.c_str(), lines);
  1437. std::string::size_type cc;
  1438. cmOStringStream ostr;
  1439. log = "";
  1440. int defects = 0;
  1441. cmsys::RegularExpression valgrindLine("^==[0-9][0-9]*==");
  1442. cmsys::RegularExpression vgFIM(
  1443. "== .*Invalid free\\(\\) / delete / delete\\[\\]");
  1444. cmsys::RegularExpression vgFMM(
  1445. "== .*Mismatched free\\(\\) / delete / delete \\[\\]");
  1446. cmsys::RegularExpression vgMLK(
  1447. "== .*[0-9][0-9]* bytes in [0-9][0-9]* blocks are definitely lost"
  1448. " in loss record [0-9][0-9]* of [0-9]");
  1449. cmsys::RegularExpression vgPAR(
  1450. "== .*Syscall param .* contains unaddressable byte\\(s\\)");
  1451. cmsys::RegularExpression vgMPK1(
  1452. "== .*[0-9][0-9]* bytes in [0-9][0-9]* blocks are possibly lost in"
  1453. " loss record [0-9][0-9]* of [0-9]");
  1454. cmsys::RegularExpression vgMPK2(
  1455. "== .*[0-9][0-9]* bytes in [0-9][0-9]* blocks are still reachable"
  1456. " in loss record [0-9][0-9]* of [0-9]");
  1457. cmsys::RegularExpression vgUMC(
  1458. "== .*Conditional jump or move depends on uninitialised value\\(s\\)");
  1459. cmsys::RegularExpression vgUMR1("== .*Use of uninitialised value of size [0-9][0-9]*");
  1460. cmsys::RegularExpression vgUMR2("== .*Invalid read of size [0-9][0-9]*");
  1461. cmsys::RegularExpression vgUMR3("== .*Jump to the invalid address ");
  1462. cmsys::RegularExpression vgUMR4(
  1463. "== .*Syscall param .* contains uninitialised or unaddressable byte\\(s\\)");
  1464. cmsys::RegularExpression vgIPW("== .*Invalid write of size [0-9]");
  1465. cmsys::RegularExpression vgABR("== .*pthread_mutex_unlock: mutex is locked by a different thread");
  1466. //double sttime = cmSystemTools::GetTime();
  1467. //std::cout << "Start test: " << lines.size() << std::endl;
  1468. for ( cc = 0; cc < lines.size(); cc ++ )
  1469. {
  1470. if ( valgrindLine.find(lines[cc]) )
  1471. {
  1472. int failure = cmCTestTestHandler::NO_MEMORY_FAULT;
  1473. if ( vgFIM.find(lines[cc]) ) { failure = cmCTestTestHandler::FIM; }
  1474. else if ( vgFMM.find(lines[cc]) ) { failure = cmCTestTestHandler::FMM; }
  1475. else if ( vgMLK.find(lines[cc]) ) { failure = cmCTestTestHandler::MLK; }
  1476. else if ( vgPAR.find(lines[cc]) ) { failure = cmCTestTestHandler::PAR; }
  1477. else if ( vgMPK1.find(lines[cc]) ){ failure = cmCTestTestHandler::MPK; }
  1478. else if ( vgMPK2.find(lines[cc]) ){ failure = cmCTestTestHandler::MPK; }
  1479. else if ( vgUMC.find(lines[cc]) ) { failure = cmCTestTestHandler::UMC; }
  1480. else if ( vgUMR1.find(lines[cc]) ){ failure = cmCTestTestHandler::UMR; }
  1481. else if ( vgUMR2.find(lines[cc]) ){ failure = cmCTestTestHandler::UMR; }
  1482. else if ( vgUMR3.find(lines[cc]) ){ failure = cmCTestTestHandler::UMR; }
  1483. else if ( vgUMR4.find(lines[cc]) ){ failure = cmCTestTestHandler::UMR; }
  1484. else if ( vgIPW.find(lines[cc]) ) { failure = cmCTestTestHandler::IPW; }
  1485. else if ( vgABR.find(lines[cc]) ) { failure = cmCTestTestHandler::ABR; }
  1486. if ( failure != cmCTestTestHandler::NO_MEMORY_FAULT )
  1487. {
  1488. ostr << "<b>" << cmCTestMemCheckResultStrings[failure] << "</b> ";
  1489. results[failure] ++;
  1490. defects ++;
  1491. }
  1492. ostr << cmCTest::MakeXMLSafe(lines[cc]) << std::endl;
  1493. }
  1494. }
  1495. //std::cout << "End test (elapsed: " << (cmSystemTools::GetTime() - sttime) << std::endl;
  1496. log = ostr.str();
  1497. if ( defects )
  1498. {
  1499. return false;
  1500. }
  1501. return true;
  1502. }
  1503. void cmCTestTestHandler::SetIncludeRegExp(const char *arg)
  1504. {
  1505. m_IncludeRegExp = arg;
  1506. }
  1507. void cmCTestTestHandler::SetExcludeRegExp(const char *arg)
  1508. {
  1509. m_ExcludeRegExp = arg;
  1510. }
  1511. void cmCTestTestHandler::SetTestsToRunInformation(const char* in)
  1512. {
  1513. this->TestsToRunString = in;
  1514. // if the argument is a file, then read it and use the contents as the string
  1515. if(cmSystemTools::FileExists(in))
  1516. {
  1517. std::ifstream fin(in);
  1518. unsigned long filelen = cmSystemTools::FileLength(in);
  1519. char* buff = new char[filelen+1];
  1520. fin.getline(buff, filelen);
  1521. buff[fin.gcount()] = 0;
  1522. this->TestsToRunString = buff;
  1523. }
  1524. }
  1525. bool cmCTestTestHandler::CleanTestOutput(std::string& output, size_t remove_threshold)
  1526. {
  1527. if ( remove_threshold == 0 )
  1528. {
  1529. return true;
  1530. }
  1531. if ( output.find("CTEST_FULL_OUTPUT") != output.npos )
  1532. {
  1533. return true;
  1534. }
  1535. cmOStringStream ostr;
  1536. std::string::size_type cc;
  1537. std::string::size_type skipsize = 0;
  1538. int inTag = 0;
  1539. int skipped = 0;
  1540. for ( cc = 0; cc < output.size(); cc ++ )
  1541. {
  1542. int ch = output[cc];
  1543. if ( ch < 0 || ch > 255 )
  1544. {
  1545. break;
  1546. }
  1547. if ( ch == '<' )
  1548. {
  1549. inTag = 1;
  1550. }
  1551. if ( !inTag )
  1552. {
  1553. int notskip = 0;
  1554. // Skip
  1555. if ( skipsize < remove_threshold )
  1556. {
  1557. ostr << static_cast<char>(ch);
  1558. notskip = 1;
  1559. }
  1560. skipsize ++;
  1561. if ( notskip && skipsize >= remove_threshold )
  1562. {
  1563. skipped = 1;
  1564. }
  1565. }
  1566. else
  1567. {
  1568. ostr << static_cast<char>(ch);
  1569. }
  1570. if ( ch == '>' )
  1571. {
  1572. inTag = 0;
  1573. }
  1574. }
  1575. if ( skipped )
  1576. {
  1577. ostr << "..." << std::endl << "The rest of the test output was removed since it exceeds the threshold of "
  1578. << remove_threshold << " characters." << std::endl;
  1579. }
  1580. output = ostr.str();
  1581. return true;
  1582. }