cmCTest.cxx 92 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157
  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 "cmake.h"
  15. #include "cmMakefile.h"
  16. #include "cmLocalGenerator.h"
  17. #include "cmGlobalGenerator.h"
  18. #include <cmsys/Directory.hxx>
  19. #include "cmListFileCache.h"
  20. #include "cmCTestSubmit.h"
  21. #include "curl/curl.h"
  22. #include <cmsys/RegularExpression.hxx>
  23. #include <cmsys/Process.h>
  24. #include <cmsys/Base64.h>
  25. #include <stdlib.h>
  26. #include <time.h>
  27. #include <math.h>
  28. #include <float.h>
  29. #define SAFEDIV(x,y) (((y)!=0)?((x)/(y)):(0))
  30. static struct tm* GetNightlyTime(std::string str)
  31. {
  32. struct tm* lctime;
  33. time_t tctime = time(0);
  34. //Convert the nightly start time to seconds. Since we are
  35. //providing only a time and a timezone, the current date of
  36. //the local machine is assumed. Consequently, nightlySeconds
  37. //is the time at which the nightly dashboard was opened or
  38. //will be opened on the date of the current client machine.
  39. //As such, this time may be in the past or in the future.
  40. time_t ntime = curl_getdate(str.c_str(), &tctime);
  41. tctime = time(0);
  42. //std::cout << "Seconds: " << tctime << std::endl;
  43. if ( ntime > tctime )
  44. {
  45. // If nightlySeconds is in the past, this is the current
  46. // open dashboard, then return nightlySeconds. If
  47. // nightlySeconds is in the future, this is the next
  48. // dashboard to be opened, so subtract 24 hours to get the
  49. // time of the current open dashboard
  50. ntime -= (24 * 60 * 60 );
  51. //std::cout << "Pick yesterday" << std::endl;
  52. }
  53. //std::cout << "nightlySeconds: " << ntime << std::endl;
  54. lctime = gmtime(&ntime);
  55. return lctime;
  56. }
  57. static std::string CleanString(std::string str)
  58. {
  59. std::string::size_type spos = str.find_first_not_of(" \n\t\r\f\v");
  60. std::string::size_type epos = str.find_last_not_of(" \n\t\r\f\v");
  61. if ( spos == str.npos )
  62. {
  63. return std::string();
  64. }
  65. if ( epos != str.npos )
  66. {
  67. epos = epos - spos + 1;
  68. }
  69. return str.substr(spos, epos);
  70. }
  71. static std::string CurrentTime()
  72. {
  73. time_t currenttime = time(0);
  74. struct tm* t = localtime(&currenttime);
  75. //return ::CleanString(ctime(&currenttime));
  76. char current_time[1024];
  77. strftime(current_time, 1000, "%a %b %d %H:%M:%S %Z %Y", t);
  78. //std::cout << "Current_Time: " << current_time << std::endl;
  79. return ::CleanString(current_time);
  80. }
  81. static const char* cmCTestErrorMatches[] = {
  82. "^[Bb]us [Ee]rror",
  83. "^[Ss]egmentation [Vv]iolation",
  84. "^[Ss]egmentation [Ff]ault",
  85. "([^ :]+):([0-9]+): ([^ \\t])",
  86. "([^:]+): error[ \\t]*[0-9]+[ \\t]*:",
  87. "^Error ([0-9]+):",
  88. "^Fatal",
  89. "^Error: ",
  90. "^Error ",
  91. "[0-9] ERROR: ",
  92. "^\"[^\"]+\", line [0-9]+: [^Ww]",
  93. "^cc[^C]*CC: ERROR File = ([^,]+), Line = ([0-9]+)",
  94. "^ld([^:])*:([ \\t])*ERROR([^:])*:",
  95. "^ild:([ \\t])*\\(undefined symbol\\)",
  96. "([^ :]+) : (error|fatal error|catastrophic error)",
  97. "([^:]+): (Error:|error|undefined reference|multiply defined)",
  98. "([^:]+)\\(([^\\)]+)\\) : (error|fatal error|catastrophic error)",
  99. "^fatal error C[0-9]+:",
  100. ": syntax error ",
  101. "^collect2: ld returned 1 exit status",
  102. "Unsatisfied symbols:",
  103. "Undefined symbols:",
  104. "^Undefined[ \\t]+first referenced",
  105. "^CMake Error:",
  106. ":[ \\t]cannot find",
  107. ":[ \\t]can't find",
  108. ": \\*\\*\\* No rule to make target \\`.*\\'. Stop",
  109. ": Invalid loader fixup for symbol",
  110. ": internal link edit command failed",
  111. ": Unrecognized option \\`.*\\'",
  112. "\", line [0-9]+\\.[0-9]+: [0-9]+-[0-9]+ \\([^W]\\)",
  113. 0
  114. };
  115. static const char* cmCTestErrorExceptions[] = {
  116. "instantiated from ",
  117. "candidates are:",
  118. ": warning",
  119. "makefile:",
  120. "Makefile:",
  121. ":[ \\t]+Where:",
  122. 0
  123. };
  124. static const char* cmCTestWarningMatches[] = {
  125. "([^ :]+):([0-9]+): warning:",
  126. "^cc[^C]*CC: WARNING File = ([^,]+), Line = ([0-9]+)",
  127. "^ld([^:])*:([ \\t])*WARNING([^:])*:",
  128. "([^:]+): warning ([0-9]+):",
  129. "^\"[^\"]+\", line [0-9]+: [Ww]arning",
  130. "([^:]+): warning[ \\t]*[0-9]+[ \\t]*:",
  131. "^Warning ([0-9]+):",
  132. "^Warning ",
  133. "WARNING: ",
  134. "([^ :]+) : warning",
  135. "([^:]+): warning",
  136. "\", line [0-9]+\\.[0-9]+: [0-9]+-[0-9]+ \\(W\\)",
  137. 0
  138. };
  139. static const char* cmCTestWarningExceptions[] = {
  140. "/usr/openwin/include/X11/Xlib\\.h:[0-9]+: warning: ANSI C\\+\\+ forbids declaration",
  141. "/usr/openwin/include/X11/Xutil\\.h:[0-9]+: warning: ANSI C\\+\\+ forbids declaration",
  142. "/usr/openwin/include/X11/XResource\\.h:[0-9]+: warning: ANSI C\\+\\+ forbids declaration",
  143. "WARNING 84 :",
  144. "WARNING 47 :",
  145. "makefile:",
  146. "Makefile:",
  147. "warning: Clock skew detected. Your build may be incomplete.",
  148. "/usr/openwin/include/GL/[^:]+:",
  149. "bind_at_load",
  150. "XrmQGetResource",
  151. "IceFlush",
  152. "warning LNK4089: all references to [^ \\t]+ discarded by .OPT:REF",
  153. "ld32: WARNING 85: definition of dataKey in",
  154. "cc: warning 422: Unknown option \"\\+b\\.\" ignored",
  155. "_with_warning_C",
  156. 0
  157. };
  158. static const char* cmCTestMemCheckResultStrings[] = {
  159. "ABR",
  160. "ABW",
  161. "ABWL",
  162. "COR",
  163. "EXU",
  164. "FFM",
  165. "FIM",
  166. "FMM",
  167. "FMR",
  168. "FMW",
  169. "FUM",
  170. "IPR",
  171. "IPW",
  172. "MAF",
  173. "MLK",
  174. "MPK",
  175. "NPR",
  176. "ODS",
  177. "PAR",
  178. "PLK",
  179. "UMC",
  180. "UMR",
  181. 0
  182. };
  183. std::string cmCTest::MakeXMLSafe(const std::string& str)
  184. {
  185. cmOStringStream ost;
  186. char buffer[10];
  187. for (std::string::size_type pos = 0; pos < str.size(); pos ++ )
  188. {
  189. unsigned char ch = str[pos];
  190. if ( (ch > 126 || ch < 32) && ch != 9 && ch != 10 && ch != 13 )
  191. {
  192. sprintf(buffer, "&gt;%d&lt;", (int)ch);
  193. //sprintf(buffer, "&#x%0x;", (unsigned int)ch);
  194. ost << buffer;
  195. }
  196. else
  197. {
  198. switch ( ch )
  199. {
  200. case '&': ost << "&amp;"; break;
  201. case '<': ost << "&lt;"; break;
  202. case '>': ost << "&gt;"; break;
  203. default: ost << ch;
  204. }
  205. }
  206. }
  207. return ost.str();
  208. }
  209. std::string cmCTest::MakeURLSafe(const std::string& str)
  210. {
  211. cmOStringStream ost;
  212. char buffer[10];
  213. for ( std::string::size_type pos = 0; pos < str.size(); pos ++ )
  214. {
  215. unsigned char ch = str[pos];
  216. if ( ( ch > 126 || ch < 32 ||
  217. ch == '&' ||
  218. ch == '%' ||
  219. ch == '+' ||
  220. ch == '=' ||
  221. ch == '@'
  222. ) && ch != 9 )
  223. {
  224. sprintf(buffer, "%02x;", (unsigned int)ch);
  225. ost << buffer;
  226. }
  227. else
  228. {
  229. ost << ch;
  230. }
  231. }
  232. return ost.str();
  233. }
  234. bool TryExecutable(const char *dir, const char *file,
  235. std::string *fullPath, const char *subdir)
  236. {
  237. // try current directory
  238. std::string tryPath;
  239. if (dir && strcmp(dir,""))
  240. {
  241. tryPath = dir;
  242. tryPath += "/";
  243. }
  244. if (subdir && strcmp(subdir,""))
  245. {
  246. tryPath += subdir;
  247. tryPath += "/";
  248. }
  249. tryPath += file;
  250. if(cmSystemTools::FileExists(tryPath.c_str()))
  251. {
  252. *fullPath = cmSystemTools::CollapseFullPath(tryPath.c_str());
  253. return true;
  254. }
  255. tryPath += cmSystemTools::GetExecutableExtension();
  256. if(cmSystemTools::FileExists(tryPath.c_str()))
  257. {
  258. *fullPath = cmSystemTools::CollapseFullPath(tryPath.c_str());
  259. return true;
  260. }
  261. return false;
  262. }
  263. cmCTest::cmCTest()
  264. {
  265. m_UseIncludeRegExp = false;
  266. m_UseExcludeRegExp = false;
  267. m_UseExcludeRegExpFirst = false;
  268. m_Verbose = false;
  269. m_DartMode = false;
  270. m_ShowOnly = false;
  271. m_RunConfigurationScript = false;
  272. m_TestModel = cmCTest::EXPERIMENTAL;
  273. m_TimeOut = 0;
  274. m_CompatibilityMode = 1;
  275. int cc;
  276. for ( cc=0; cc < cmCTest::LAST_TEST; cc ++ )
  277. {
  278. m_Tests[cc] = 0;
  279. }
  280. }
  281. void cmCTest::Initialize()
  282. {
  283. m_ToplevelPath = cmSystemTools::GetCurrentWorkingDirectory();
  284. cmSystemTools::ConvertToUnixSlashes(m_ToplevelPath);
  285. // parse the dart test file
  286. std::ifstream fin("DartConfiguration.tcl");
  287. if(!fin)
  288. {
  289. return;
  290. }
  291. char buffer[1024];
  292. while ( fin )
  293. {
  294. buffer[0] = 0;
  295. fin.getline(buffer, 1023);
  296. buffer[1023] = 0;
  297. std::string line = ::CleanString(buffer);
  298. if(line.size() == 0)
  299. {
  300. continue;
  301. }
  302. while ( fin && (line[line.size()-1] == '\\') )
  303. {
  304. line = line.substr(0, line.size()-1);
  305. buffer[0] = 0;
  306. fin.getline(buffer, 1023);
  307. buffer[1023] = 0;
  308. line += ::CleanString(buffer);
  309. }
  310. if ( line[0] == '#' )
  311. {
  312. continue;
  313. }
  314. std::string::size_type cpos = line.find_first_of(":");
  315. if ( cpos == line.npos )
  316. {
  317. continue;
  318. }
  319. std::string key = line.substr(0, cpos);
  320. std::string value = ::CleanString(line.substr(cpos+1, line.npos));
  321. m_DartConfiguration[key] = value;
  322. }
  323. fin.close();
  324. if ( m_DartMode )
  325. {
  326. m_TimeOut = atoi(m_DartConfiguration["TimeOut"].c_str());
  327. std::string testingDir = m_ToplevelPath + "/Testing";
  328. if ( cmSystemTools::FileExists(testingDir.c_str()) )
  329. {
  330. if ( !cmSystemTools::FileIsDirectory(testingDir.c_str()) )
  331. {
  332. std::cerr << "File " << testingDir << " is in the place of the testing directory"
  333. << std::endl;
  334. return;
  335. }
  336. }
  337. else
  338. {
  339. if ( !cmSystemTools::MakeDirectory(testingDir.c_str()) )
  340. {
  341. std::cerr << "Cannot create directory " << testingDir
  342. << std::endl;
  343. return;
  344. }
  345. }
  346. std::string tagfile = testingDir + "/TAG";
  347. std::ifstream tfin(tagfile.c_str());
  348. std::string tag;
  349. time_t tctime = time(0);
  350. struct tm *lctime = gmtime(&tctime);
  351. if ( tfin )
  352. {
  353. tfin >> tag;
  354. tfin.close();
  355. int year = 0;
  356. int mon = 0;
  357. int day = 0;
  358. int hour = 0;
  359. int min = 0;
  360. sscanf(tag.c_str(), "%04d%02d%02d-%02d%02d",
  361. &year, &mon, &day, &hour, &min);
  362. if ( year != lctime->tm_year + 1900 ||
  363. mon != lctime->tm_mon+1 ||
  364. day != lctime->tm_mday )
  365. {
  366. tag = "";
  367. }
  368. }
  369. if ( tag.size() == 0 || m_Tests[cmCTest::START_TEST] || m_Tests[ALL_TEST])
  370. {
  371. //std::cout << "TestModel: " << this->GetTestModelString() << std::endl;
  372. //std::cout << "TestModel: " << m_TestModel << std::endl;
  373. if ( m_TestModel == cmCTest::NIGHTLY )
  374. {
  375. lctime = ::GetNightlyTime(m_DartConfiguration["NightlyStartTime"]);
  376. }
  377. char datestring[100];
  378. sprintf(datestring, "%04d%02d%02d-%02d%02d",
  379. lctime->tm_year + 1900,
  380. lctime->tm_mon+1,
  381. lctime->tm_mday,
  382. lctime->tm_hour,
  383. lctime->tm_min);
  384. tag = datestring;
  385. std::ofstream ofs(tagfile.c_str());
  386. if ( ofs )
  387. {
  388. ofs << tag << std::endl;
  389. }
  390. ofs.close();
  391. std::cout << "Create new tag: " << tag << std::endl;
  392. }
  393. m_CurrentTag = tag;
  394. }
  395. }
  396. bool cmCTest::SetTest(const char* ttype)
  397. {
  398. if ( cmSystemTools::LowerCase(ttype) == "all" )
  399. {
  400. m_Tests[cmCTest::ALL_TEST] = 1;
  401. }
  402. else if ( cmSystemTools::LowerCase(ttype) == "start" )
  403. {
  404. m_Tests[cmCTest::START_TEST] = 1;
  405. }
  406. else if ( cmSystemTools::LowerCase(ttype) == "update" )
  407. {
  408. m_Tests[cmCTest::UPDATE_TEST] = 1;
  409. }
  410. else if ( cmSystemTools::LowerCase(ttype) == "configure" )
  411. {
  412. m_Tests[cmCTest::CONFIGURE_TEST] = 1;
  413. }
  414. else if ( cmSystemTools::LowerCase(ttype) == "build" )
  415. {
  416. m_Tests[cmCTest::BUILD_TEST] = 1;
  417. }
  418. else if ( cmSystemTools::LowerCase(ttype) == "test" )
  419. {
  420. m_Tests[cmCTest::TEST_TEST] = 1;
  421. }
  422. else if ( cmSystemTools::LowerCase(ttype) == "coverage" )
  423. {
  424. m_Tests[cmCTest::COVERAGE_TEST] = 1;
  425. }
  426. else if ( cmSystemTools::LowerCase(ttype) == "memcheck" )
  427. {
  428. m_Tests[cmCTest::MEMCHECK_TEST] = 1;
  429. }
  430. else if ( cmSystemTools::LowerCase(ttype) == "submit" )
  431. {
  432. m_Tests[cmCTest::SUBMIT_TEST] = 1;
  433. }
  434. else
  435. {
  436. std::cerr << "Don't know about test \"" << ttype << "\" yet..." << std::endl;
  437. return false;
  438. }
  439. return true;
  440. }
  441. void cmCTest::Finalize()
  442. {
  443. }
  444. std::string cmCTest::FindTheExecutable(const char *exe)
  445. {
  446. std::string fullPath = "";
  447. std::string dir;
  448. std::string file;
  449. cmSystemTools::SplitProgramPath(exe, dir, file);
  450. if(m_ConfigType != "" &&
  451. ::TryExecutable(dir.c_str(), file.c_str(), &fullPath,
  452. m_ConfigType.c_str()))
  453. {
  454. return fullPath;
  455. }
  456. if (::TryExecutable(dir.c_str(),file.c_str(),&fullPath,"."))
  457. {
  458. return fullPath;
  459. }
  460. if (::TryExecutable(dir.c_str(),file.c_str(),&fullPath,""))
  461. {
  462. return fullPath;
  463. }
  464. if ( m_ConfigType == "" )
  465. {
  466. // No config type, so try to guess it
  467. if (::TryExecutable(dir.c_str(),file.c_str(),&fullPath,"Release"))
  468. {
  469. return fullPath;
  470. }
  471. if (::TryExecutable(dir.c_str(),file.c_str(),&fullPath,"Debug"))
  472. {
  473. return fullPath;
  474. }
  475. if (::TryExecutable(dir.c_str(),file.c_str(),&fullPath,"MinSizeRel"))
  476. {
  477. return fullPath;
  478. }
  479. if (::TryExecutable(dir.c_str(),file.c_str(),&fullPath,"RelWithDebInfo"))
  480. {
  481. return fullPath;
  482. }
  483. }
  484. // if everything else failed, check the users path
  485. if (dir != "")
  486. {
  487. std::string path = cmSystemTools::FindProgram(file.c_str());
  488. if (path != "")
  489. {
  490. return path;
  491. }
  492. }
  493. if ( m_ConfigType != "" )
  494. {
  495. dir += "/";
  496. dir += m_ConfigType;
  497. dir += "/";
  498. dir += file;
  499. cmSystemTools::Error("config type specified on the command line, but test executable not found.",
  500. dir.c_str());
  501. return "";
  502. }
  503. return fullPath;
  504. }
  505. int cmCTest::UpdateDirectory()
  506. {
  507. int count = 0;
  508. std::string::size_type cc, kk;
  509. std::string cvsCommand = m_DartConfiguration["CVSCommand"];
  510. if ( cvsCommand.size() == 0 )
  511. {
  512. std::cerr << "Cannot find CVSCommand key in the DartConfiguration.tcl" << std::endl;
  513. return -1;
  514. }
  515. std::string cvsOptions = m_DartConfiguration["CVSUpdateOptions"];
  516. if ( cvsOptions.size() == 0 )
  517. {
  518. std::cerr << "Cannot find CVSUpdateOptions key in the DartConfiguration.tcl" << std::endl;
  519. return -1;
  520. }
  521. std::string sourceDirectory = m_DartConfiguration["SourceDirectory"];
  522. if ( sourceDirectory.size() == 0 )
  523. {
  524. std::cerr << "Cannot find SourceDirectory key in the DartConfiguration.tcl" << std::endl;
  525. return -1;
  526. }
  527. std::string extra_update_opts;
  528. if ( m_TestModel == cmCTest::NIGHTLY )
  529. {
  530. struct tm* t = ::GetNightlyTime(m_DartConfiguration["NightlyStartTime"]);
  531. char current_time[1024];
  532. sprintf(current_time, "%04d-%02d-%02d %02d:%02d:%02d UTC",
  533. t->tm_year + 1900,
  534. t->tm_mon + 1,
  535. t->tm_mday,
  536. t->tm_hour,
  537. t->tm_min,
  538. t->tm_sec);
  539. std::string today_update_date = current_time;
  540. extra_update_opts += "-D \"" + today_update_date +"\"";
  541. //std::cout << "Update: " << extra_update_opts << std::endl;
  542. }
  543. std::string command = cvsCommand + " -z3 update " + cvsOptions +
  544. " " + extra_update_opts;
  545. std::ofstream os;
  546. if ( !this->OpenOutputFile(m_CurrentTag, "Update.xml", os) )
  547. {
  548. std::cerr << "Cannot open log file" << std::endl;
  549. }
  550. std::string start_time = ::CurrentTime();
  551. std::string goutput;
  552. int retVal = 0;
  553. bool res = true;
  554. std::ofstream ofs;
  555. if ( !m_ShowOnly )
  556. {
  557. res = cmSystemTools::RunSingleCommand(command.c_str(), &goutput,
  558. &retVal, sourceDirectory.c_str(),
  559. m_Verbose, 0 /*m_TimeOut*/);
  560. if ( this->OpenOutputFile("Temporary", "LastUpdate.log", ofs) )
  561. {
  562. ofs << goutput << std::endl;;
  563. }
  564. }
  565. else
  566. {
  567. std::cout << "Update with command: " << command << std::endl;
  568. }
  569. os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
  570. << "<Update mode=\"Client\">\n"
  571. << "\t<Site>" <<m_DartConfiguration["Site"] << "</Site>\n"
  572. << "\t<BuildName>" << m_DartConfiguration["BuildName"]
  573. << "</BuildName>\n"
  574. << "\t<BuildStamp>" << m_CurrentTag << "-"
  575. << this->GetTestModelString() << "</BuildStamp>" << std::endl;
  576. os << "\t<StartDateTime>" << start_time << "</StartDateTime>\n"
  577. << "\t<UpdateCommand>" << command << "</UpdateCommand>\n"
  578. << "\t<UpdateReturnStatus>";
  579. if ( retVal )
  580. {
  581. os << goutput;
  582. }
  583. os << "</UpdateReturnStatus>" << std::endl;
  584. std::vector<cmStdString> lines;
  585. cmSystemTools::Split(goutput.c_str(), lines);
  586. std::cout << "Updated; gathering version information" << std::endl;
  587. cmsys::RegularExpression date_author("^date: +([^;]+); +author: +([^;]+); +state: +[^;]+;");
  588. cmsys::RegularExpression revision("^revision +([^ ]*) *$");
  589. cmsys::RegularExpression end_of_file("^=============================================================================$");
  590. cmsys::RegularExpression end_of_comment("^----------------------------$");
  591. std::string current_path = "";
  592. bool first_file = true;
  593. cmCTest::AuthorsToUpdatesMap authors_files_map;
  594. int num_updated = 0;
  595. int num_modified = 0;
  596. int num_conflicting = 0;
  597. for ( cc= 0 ; cc < lines.size(); cc ++ )
  598. {
  599. const char* line = lines[cc].c_str();
  600. char mod = line[0];
  601. if ( line[1] == ' ' && mod != '?' )
  602. {
  603. count ++;
  604. const char* file = line + 2;
  605. //std::cout << "Line" << cc << ": " << mod << " - " << file << std::endl;
  606. std::string logcommand = cvsCommand + " -z3 log -N " + file;
  607. //std::cout << "Do log: " << logcommand << std::endl;
  608. std::string output;
  609. res = cmSystemTools::RunSingleCommand(logcommand.c_str(), &output,
  610. &retVal, sourceDirectory.c_str(),
  611. m_Verbose, 0 /*m_TimeOut*/);
  612. if ( ofs )
  613. {
  614. ofs << output << std::endl;
  615. }
  616. if ( res && retVal == 0)
  617. {
  618. //std::cout << output << std::endl;
  619. std::vector<cmStdString> ulines;
  620. cmSystemTools::Split(output.c_str(), ulines);
  621. std::string::size_type sline = 0;
  622. std::string srevision1 = "Unknown";
  623. std::string sdate1 = "Unknown";
  624. std::string sauthor1 = "Unknown";
  625. std::string semail1 = "Unknown";
  626. std::string comment1 = "";
  627. std::string srevision2 = "Unknown";
  628. std::string sdate2 = "Unknown";
  629. std::string sauthor2 = "Unknown";
  630. std::string comment2 = "";
  631. std::string semail2 = "Unknown";
  632. bool have_first = false;
  633. bool have_second = false;
  634. for ( kk = 0; kk < ulines.size(); kk ++ )
  635. {
  636. const char* clp = ulines[kk].c_str();
  637. if ( !have_second && !sline && revision.find(clp) )
  638. {
  639. if ( !have_first )
  640. {
  641. srevision1 = revision.match(1);
  642. }
  643. else
  644. {
  645. srevision2 = revision.match(1);
  646. }
  647. }
  648. else if ( !have_second && !sline && date_author.find(clp) )
  649. {
  650. sline = kk + 1;
  651. if ( !have_first )
  652. {
  653. sdate1 = date_author.match(1);
  654. sauthor1 = date_author.match(2);
  655. }
  656. else
  657. {
  658. sdate2 = date_author.match(1);
  659. sauthor2 = date_author.match(2);
  660. }
  661. }
  662. else if ( sline && end_of_comment.find(clp) || end_of_file.find(clp))
  663. {
  664. if ( !have_first )
  665. {
  666. have_first = true;
  667. }
  668. else if ( !have_second )
  669. {
  670. have_second = true;
  671. }
  672. sline = 0;
  673. }
  674. else if ( sline )
  675. {
  676. if ( !have_first )
  677. {
  678. comment1 += clp;
  679. comment1 += "\n";
  680. }
  681. else
  682. {
  683. comment2 += clp;
  684. comment2 += "\n";
  685. }
  686. }
  687. }
  688. if ( mod == 'M' )
  689. {
  690. comment1 = "Locally modified file\n";
  691. }
  692. if ( mod == 'C' )
  693. {
  694. comment1 = "Conflict while updating\n";
  695. }
  696. std::string path = cmSystemTools::GetFilenamePath(file);
  697. std::string fname = cmSystemTools::GetFilenameName(file);
  698. if ( path != current_path )
  699. {
  700. if ( !first_file )
  701. {
  702. os << "\t</Directory>" << std::endl;
  703. }
  704. else
  705. {
  706. first_file = false;
  707. }
  708. os << "\t<Directory>\n"
  709. << "\t\t<Name>" << path << "</Name>" << std::endl;
  710. }
  711. if ( mod == 'C' )
  712. {
  713. num_conflicting ++;
  714. os << "\t<Conflicting>" << std::endl;
  715. }
  716. else if ( mod == 'M' )
  717. {
  718. num_modified ++;
  719. os << "\t<Modified>" << std::endl;
  720. }
  721. else
  722. {
  723. num_updated ++;
  724. os << "\t<Updated>" << std::endl;
  725. }
  726. if ( srevision2 == "Unknown" )
  727. {
  728. srevision2 = srevision1;
  729. }
  730. os << "\t\t<File Directory=\"" << path << "\">" << fname
  731. << "</File>\n"
  732. << "\t\t<Directory>" << path << "</Directory>\n"
  733. << "\t\t<FullName>" << file << "</FullName>\n"
  734. << "\t\t<CheckinDate>" << sdate1 << "</CheckinDate>\n"
  735. << "\t\t<Author>" << sauthor1 << "</Author>\n"
  736. << "\t\t<Email>" << semail1 << "</Email>\n"
  737. << "\t\t<Log>" << this->MakeXMLSafe(comment1) << "</Log>\n"
  738. << "\t\t<Revision>" << srevision1 << "</Revision>\n"
  739. << "\t\t<PriorRevision>" << srevision2 << "</PriorRevision>"
  740. << std::endl;
  741. if ( srevision2 != srevision1 )
  742. {
  743. os
  744. << "\t\t<Revisions>\n"
  745. << "\t\t\t<Revision>" << srevision1 << "</Revision>\n"
  746. << "\t\t\t<PreviousRevision>" << srevision2 << "</PreviousRevision>\n"
  747. << "\t\t\t<Author>" << sauthor1<< "</Author>\n"
  748. << "\t\t\t<Date>" << sdate1 << "</Date>\n"
  749. << "\t\t\t<Comment>" << this->MakeXMLSafe(comment1) << "</Comment>\n"
  750. << "\t\t\t<Email>" << semail1 << "</Email>\n"
  751. << "\t\t</Revisions>\n"
  752. << "\t\t<Revisions>\n"
  753. << "\t\t\t<Revision>" << srevision2 << "</Revision>\n"
  754. << "\t\t\t<PreviousRevision>" << srevision2 << "</PreviousRevision>\n"
  755. << "\t\t\t<Author>" << sauthor2<< "</Author>\n"
  756. << "\t\t\t<Date>" << sdate2 << "</Date>\n"
  757. << "\t\t\t<Comment>" << this->MakeXMLSafe(comment2) << "</Comment>\n"
  758. << "\t\t\t<Email>" << semail2 << "</Email>\n"
  759. << "\t\t</Revisions>" << std::endl;
  760. }
  761. if ( mod == 'C' )
  762. {
  763. os << "\t</Conflicting>" << std::endl;
  764. }
  765. else if ( mod == 'M' )
  766. {
  767. os << "\t</Modified>" << std::endl;
  768. }
  769. else
  770. {
  771. os << "\t</Updated>" << std::endl;
  772. }
  773. cmCTest::UpdateFiles *u = &authors_files_map[sauthor1];
  774. cmCTest::StringPair p;
  775. p.first = path;
  776. p.second = fname;
  777. u->push_back(p);
  778. current_path = path;
  779. }
  780. }
  781. }
  782. if ( num_updated )
  783. {
  784. std::cout << "Found " << num_updated << " updated files" << std::endl;
  785. }
  786. if ( num_modified )
  787. {
  788. std::cout << "Found " << num_modified << " locally modified files"
  789. << std::endl;
  790. }
  791. if ( num_conflicting )
  792. {
  793. std::cout << "Found " << num_conflicting << " conflicting files"
  794. << std::endl;
  795. }
  796. if ( !first_file )
  797. {
  798. os << "\t</Directory>" << std::endl;
  799. }
  800. cmCTest::AuthorsToUpdatesMap::iterator it;
  801. for ( it = authors_files_map.begin();
  802. it != authors_files_map.end();
  803. it ++ )
  804. {
  805. os << "\t<Author>\n"
  806. << "\t\t<Name>" << it->first << "</Name>" << std::endl;
  807. cmCTest::UpdateFiles *u = &(it->second);
  808. for ( cc = 0; cc < u->size(); cc ++ )
  809. {
  810. os << "\t\t<File Directory=\"" << (*u)[cc].first << "\">"
  811. << (*u)[cc].second << "</File>" << std::endl;
  812. }
  813. os << "\t</Author>" << std::endl;
  814. }
  815. //std::cout << "End" << std::endl;
  816. std::string end_time = ::CurrentTime();
  817. os << "\t<EndDateTime>" << end_time << "</EndDateTime>\n"
  818. << "</Update>" << std::endl;
  819. if ( ofs )
  820. {
  821. ofs.close();
  822. }
  823. if (! res || retVal )
  824. {
  825. std::cerr << "Error(s) when updating the project" << std::endl;
  826. std::cerr << "Output: " << goutput << std::endl;
  827. return -1;
  828. }
  829. return count;
  830. }
  831. int cmCTest::ConfigureDirectory()
  832. {
  833. std::cout << "Configure project" << std::endl;
  834. std::string cCommand = m_DartConfiguration["ConfigureCommand"];
  835. if ( cCommand.size() == 0 )
  836. {
  837. std::cerr << "Cannot find ConfigureCommand key in the DartConfiguration.tcl"
  838. << std::endl;
  839. return 1;
  840. }
  841. std::string buildDirectory = m_DartConfiguration["BuildDirectory"];
  842. if ( buildDirectory.size() == 0 )
  843. {
  844. std::cerr << "Cannot find BuildDirectory key in the DartConfiguration.tcl" << std::endl;
  845. return 1;
  846. }
  847. std::string output;
  848. int retVal = 0;
  849. int res = 0;
  850. if ( !m_ShowOnly )
  851. {
  852. std::ofstream os;
  853. if ( !this->OpenOutputFile(m_CurrentTag, "Configure.xml", os) )
  854. {
  855. std::cerr << "Cannot open log file" << std::endl;
  856. }
  857. std::string start_time = ::CurrentTime();
  858. std::ofstream ofs;
  859. this->OpenOutputFile("Temporary", "LastConfigure.log", ofs);
  860. res = this->RunMakeCommand(cCommand.c_str(), &output,
  861. &retVal, buildDirectory.c_str(),
  862. m_Verbose, 0, ofs);
  863. if ( ofs )
  864. {
  865. ofs.close();
  866. }
  867. if ( os )
  868. {
  869. this->StartXML(os);
  870. os << "<Configure>\n"
  871. << "\t<StartDateTime>" << start_time << "</StartDateTime>" << std::endl;
  872. if ( res == cmsysProcess_State_Exited && retVal )
  873. {
  874. os << retVal;
  875. }
  876. os << "<ConfigureCommand>" << cCommand.c_str() << "</ConfigureCommand>" << std::endl;
  877. //std::cout << "End" << std::endl;
  878. os << "<Log>" << this->MakeXMLSafe(output) << "</Log>" << std::endl;
  879. std::string end_time = ::CurrentTime();
  880. os << "\t<ConfigureStatus>" << retVal << "</ConfigureStatus>\n"
  881. << "\t<EndDateTime>" << end_time << "</EndDateTime>\n"
  882. << "</Configure>" << std::endl;
  883. this->EndXML(os);
  884. }
  885. }
  886. else
  887. {
  888. std::cout << "Configure with command: " << cCommand << std::endl;
  889. }
  890. if (! res || retVal )
  891. {
  892. std::cerr << "Error(s) when updating the project" << std::endl;
  893. return 1;
  894. }
  895. return 0;
  896. }
  897. int cmCTest::BuildDirectory()
  898. {
  899. std::cout << "Build project" << std::endl;
  900. std::string makeCommand = m_DartConfiguration["MakeCommand"];
  901. if ( makeCommand.size() == 0 )
  902. {
  903. std::cerr << "Cannot find MakeCommand key in the DartConfiguration.tcl" << std::endl;
  904. return 1;
  905. }
  906. std::string buildDirectory = m_DartConfiguration["BuildDirectory"];
  907. if ( buildDirectory.size() == 0 )
  908. {
  909. std::cerr << "Cannot find BuildDirectory key in the DartConfiguration.tcl" << std::endl;
  910. return 1;
  911. }
  912. std::ofstream ofs;
  913. if ( !this->OpenOutputFile("Temporary", "LastBuild.log", ofs) )
  914. {
  915. std::cerr << "Cannot create LastBuild.log file" << std::endl;
  916. }
  917. m_StartBuild = ::CurrentTime();
  918. std::string output;
  919. int retVal = 0;
  920. int res = cmsysProcess_State_Exited;
  921. if ( !m_ShowOnly )
  922. {
  923. res = this->RunMakeCommand(makeCommand.c_str(), &output,
  924. &retVal, buildDirectory.c_str(),
  925. m_Verbose, 0, ofs);
  926. }
  927. else
  928. {
  929. std::cout << "Build with command: " << makeCommand << std::endl;
  930. }
  931. m_EndBuild = ::CurrentTime();
  932. if (res != cmsysProcess_State_Exited || retVal )
  933. {
  934. std::cerr << "Error(s) when building project" << std::endl;
  935. }
  936. if ( ofs )
  937. {
  938. ofs.close();
  939. }
  940. // Parsing of output for errors and warnings.
  941. std::vector<cmStdString> lines;
  942. cmSystemTools::Split(output.c_str(), lines);
  943. // Lines are marked:
  944. // 0 - nothing
  945. // 1 - error
  946. // > 1 - warning
  947. std::vector<int> markedLines(lines.size(), 0);
  948. int cc;
  949. // Errors
  950. for ( cc = 0; cmCTestErrorMatches[cc]; cc ++ )
  951. {
  952. cmsys::RegularExpression re(cmCTestErrorMatches[cc]);
  953. cmCTest::tm_VectorOfStrings::size_type kk;
  954. for ( kk = 0; kk < lines.size(); kk ++ )
  955. {
  956. if ( re.find(lines[kk]) )
  957. {
  958. markedLines[kk] = 1;
  959. }
  960. }
  961. }
  962. // Warnings
  963. for ( cc = 0; cmCTestWarningMatches[cc]; cc ++ )
  964. {
  965. cmsys::RegularExpression re(cmCTestWarningMatches[cc]);
  966. cmCTest::tm_VectorOfStrings::size_type kk;
  967. for ( kk = 0; kk < lines.size(); kk ++ )
  968. {
  969. if ( re.find(lines[kk]) )
  970. {
  971. markedLines[kk] += 2;
  972. }
  973. }
  974. }
  975. // Errors exceptions
  976. for ( cc = 0; cmCTestErrorExceptions[cc]; cc ++ )
  977. {
  978. cmsys::RegularExpression re(cmCTestErrorExceptions[cc]);
  979. std::vector<int>::size_type kk;
  980. for ( kk =0; kk < markedLines.size(); kk ++ )
  981. {
  982. if ( markedLines[kk] == 1 )
  983. {
  984. if ( re.find(lines[kk]) )
  985. {
  986. markedLines[kk] = 0;
  987. }
  988. }
  989. }
  990. }
  991. // Warning exceptions
  992. for ( cc = 0; cmCTestWarningExceptions[cc]; cc ++ )
  993. {
  994. cmsys::RegularExpression re(cmCTestWarningExceptions[cc]);
  995. std::vector<int>::size_type kk;
  996. for ( kk =0; kk < markedLines.size(); kk ++ )
  997. {
  998. if ( markedLines[kk] > 1 )
  999. {
  1000. if ( re.find(lines[kk]) )
  1001. {
  1002. markedLines[kk] = 0;
  1003. }
  1004. }
  1005. }
  1006. }
  1007. std::vector<cmCTestBuildErrorWarning> errorsWarnings;
  1008. int errors = 0;
  1009. int warnings = 0;
  1010. std::vector<int>::size_type kk;
  1011. cmCTestBuildErrorWarning errorwarning;
  1012. for ( kk =0; kk < markedLines.size(); kk ++ )
  1013. {
  1014. errorwarning.m_LineNumber = -1;
  1015. bool found = false;
  1016. if ( markedLines[kk] == 1 )
  1017. {
  1018. //std::cout << "Error: " << lines[kk] << std::endl;
  1019. errorwarning.m_Error = true;
  1020. found = true;
  1021. }
  1022. else if ( markedLines[kk] > 1 )
  1023. {
  1024. //std::cout << "Warning: " << lines[kk] << std::endl;
  1025. errorwarning.m_Error = false;
  1026. found = true;
  1027. }
  1028. if ( found )
  1029. {
  1030. errorwarning.m_LogLine = static_cast<int>(kk+1);
  1031. errorwarning.m_Text = lines[kk];
  1032. errorwarning.m_PreContext = "";
  1033. errorwarning.m_PostContext = "";
  1034. std::vector<int>::size_type jj;
  1035. std::vector<int>::size_type ll = 0;
  1036. if ( kk > 6 )
  1037. {
  1038. ll = kk - 6;
  1039. }
  1040. for ( jj = kk;
  1041. jj > 0 && jj > ll /* && markedLines[jj] == 0 */;
  1042. jj -- );
  1043. for (; jj < kk; jj ++ )
  1044. {
  1045. errorwarning.m_PreContext += lines[jj] + "\n";
  1046. }
  1047. for ( jj = kk+1;
  1048. jj < lines.size() && jj < kk + 7 /* && markedLines[jj] == 0*/;
  1049. jj ++ )
  1050. {
  1051. errorwarning.m_PostContext += lines[jj] + "\n";
  1052. }
  1053. errorsWarnings.push_back(errorwarning);
  1054. if ( errorwarning.m_Error )
  1055. {
  1056. errors ++;
  1057. }
  1058. else
  1059. {
  1060. warnings ++;
  1061. }
  1062. }
  1063. }
  1064. std::cout << " " << errors << " Compiler errors" << std::endl;
  1065. std::cout << " " << warnings << " Compiler warnings" << std::endl;
  1066. if( !this->OpenOutputFile(m_CurrentTag, "Build.xml", ofs) )
  1067. {
  1068. std::cerr << "Cannot create build XML file" << std::endl;
  1069. return 1;
  1070. }
  1071. this->GenerateDartBuildOutput(ofs, errorsWarnings);
  1072. return 0;
  1073. }
  1074. int cmCTest::CoverageDirectory()
  1075. {
  1076. std::cout << "Performing coverage" << std::endl;
  1077. cmCTest::tm_VectorOfStrings files;
  1078. cmCTest::tm_VectorOfStrings cfiles;
  1079. cmCTest::tm_VectorOfStrings cdirs;
  1080. bool done = false;
  1081. std::string::size_type cc;
  1082. std::string glob;
  1083. std::map<std::string, std::string> allsourcefiles;
  1084. std::map<std::string, std::string> allbinaryfiles;
  1085. std::string start_time = ::CurrentTime();
  1086. // Find all source files.
  1087. std::string sourceDirectory = m_DartConfiguration["SourceDirectory"];
  1088. if ( sourceDirectory.size() == 0 )
  1089. {
  1090. std::cerr << "Cannot find SourceDirectory key in the DartConfiguration.tcl" << std::endl;
  1091. return 1;
  1092. }
  1093. std::string coverageCommand = m_DartConfiguration["CoverageCommand"];
  1094. if ( coverageCommand.size() == 0 )
  1095. {
  1096. std::cerr << "Coverage command not defined in DartConfiguration.tcl" << std::endl;
  1097. return 1;
  1098. }
  1099. cdirs.push_back(sourceDirectory);
  1100. while ( !done )
  1101. {
  1102. if ( cdirs.size() <= 0 )
  1103. {
  1104. break;
  1105. }
  1106. glob = cdirs[cdirs.size()-1] + "/*";
  1107. //std::cout << "Glob: " << glob << std::endl;
  1108. cdirs.pop_back();
  1109. if ( cmSystemTools::SimpleGlob(glob, cfiles, 1) )
  1110. {
  1111. for ( cc = 0; cc < cfiles.size(); cc ++ )
  1112. {
  1113. allsourcefiles[cmSystemTools::GetFilenameName(cfiles[cc])] = cfiles[cc];
  1114. }
  1115. }
  1116. if ( cmSystemTools::SimpleGlob(glob, cfiles, -1) )
  1117. {
  1118. for ( cc = 0; cc < cfiles.size(); cc ++ )
  1119. {
  1120. if ( cfiles[cc] != "." && cfiles[cc] != ".." )
  1121. {
  1122. cdirs.push_back(cfiles[cc]);
  1123. }
  1124. }
  1125. }
  1126. }
  1127. // find all binary files
  1128. cdirs.push_back(cmSystemTools::GetCurrentWorkingDirectory());
  1129. while ( !done )
  1130. {
  1131. if ( cdirs.size() <= 0 )
  1132. {
  1133. break;
  1134. }
  1135. glob = cdirs[cdirs.size()-1] + "/*";
  1136. //std::cout << "Glob: " << glob << std::endl;
  1137. cdirs.pop_back();
  1138. if ( cmSystemTools::SimpleGlob(glob, cfiles, 1) )
  1139. {
  1140. for ( cc = 0; cc < cfiles.size(); cc ++ )
  1141. {
  1142. allbinaryfiles[cmSystemTools::GetFilenameName(cfiles[cc])] = cfiles[cc];
  1143. }
  1144. }
  1145. if ( cmSystemTools::SimpleGlob(glob, cfiles, -1) )
  1146. {
  1147. for ( cc = 0; cc < cfiles.size(); cc ++ )
  1148. {
  1149. if ( cfiles[cc] != "." && cfiles[cc] != ".." )
  1150. {
  1151. cdirs.push_back(cfiles[cc]);
  1152. }
  1153. }
  1154. }
  1155. }
  1156. std::map<std::string, std::string>::iterator sit;
  1157. for ( sit = allbinaryfiles.begin(); sit != allbinaryfiles.end(); sit ++ )
  1158. {
  1159. const std::string& fname = sit->second;
  1160. //std::cout << "File: " << fname << std::endl;
  1161. if ( strcmp(fname.substr(fname.size()-3, 3).c_str(), ".da") == 0 )
  1162. {
  1163. files.push_back(fname);
  1164. }
  1165. }
  1166. if ( files.size() == 0 )
  1167. {
  1168. std::cerr << "Cannot find any coverage information files (.da)" << std::endl;
  1169. return 1;
  1170. }
  1171. std::ofstream log;
  1172. if (!this->OpenOutputFile("Temporary", "Coverage.log", log))
  1173. {
  1174. std::cerr << "Cannot open log file" << std::endl;
  1175. return 1;
  1176. }
  1177. log.close();
  1178. if (!this->OpenOutputFile(m_CurrentTag, "Coverage.xml", log))
  1179. {
  1180. std::cerr << "Cannot open log file" << std::endl;
  1181. return 1;
  1182. }
  1183. std::string opath = m_ToplevelPath + "/Testing/Temporary/Coverage";
  1184. cmSystemTools::MakeDirectory(opath.c_str());
  1185. for ( cc = 0; cc < files.size(); cc ++ )
  1186. {
  1187. std::string command = coverageCommand + " -o \"" +
  1188. cmSystemTools::GetFilenamePath(files[cc]) +
  1189. "\" -l \"" + files[cc] + "\"";
  1190. std::string output;
  1191. int retVal = 0;
  1192. //std::cout << "Run gcov on " << files[cc] << std::flush;
  1193. //std::cout << " --- Run [" << command << "]" << std::endl;
  1194. bool res = true;
  1195. if ( !m_ShowOnly )
  1196. {
  1197. res = cmSystemTools::RunSingleCommand(command.c_str(), &output,
  1198. &retVal, opath.c_str(),
  1199. m_Verbose, 0 /*m_TimeOut*/);
  1200. }
  1201. if ( res && retVal == 0 )
  1202. {
  1203. //std::cout << " - done" << std::endl;
  1204. }
  1205. else
  1206. {
  1207. std::cerr << "Run gcov on " << files[cc] << std::flush;
  1208. std::cerr << " [" << command << "]" << std::endl;
  1209. std::cerr << " - fail" << std::endl;
  1210. }
  1211. }
  1212. files.clear();
  1213. glob = opath + "/*";
  1214. if ( !cmSystemTools::SimpleGlob(glob, cfiles, 1) )
  1215. {
  1216. std::cerr << "Cannot found any coverage files" << std::endl;
  1217. return 1;
  1218. }
  1219. std::map<std::string, cmCTest::tm_VectorOfStrings > sourcefiles;
  1220. for ( cc = 0; cc < cfiles.size(); cc ++ )
  1221. {
  1222. std::string& fname = cfiles[cc];
  1223. // std::cout << "File: " << fname << std::endl;
  1224. if ( strcmp(fname.substr(fname.size()-5, 5).c_str(), ".gcov") == 0 )
  1225. {
  1226. files.push_back(fname);
  1227. std::string::size_type pos = fname.find(".da.");
  1228. std::string::size_type pos2 = fname.find(".da##");
  1229. if(pos2 != fname.npos)
  1230. {
  1231. pos = pos2+1;
  1232. }
  1233. if ( pos != fname.npos )
  1234. {
  1235. pos += 4;
  1236. std::string::size_type epos = fname.size() - pos - strlen(".gcov");
  1237. std::string nf = fname.substr(pos, epos);
  1238. //std::cout << "Substring: " << nf << std::endl;
  1239. if ( allsourcefiles.find(nf) != allsourcefiles.end() ||
  1240. allbinaryfiles.find(nf) != allbinaryfiles.end() )
  1241. {
  1242. cmCTest::tm_VectorOfStrings &cvec = sourcefiles[nf];
  1243. cvec.push_back(fname);
  1244. }
  1245. }
  1246. }
  1247. }
  1248. // for ( cc = 0; cc < files.size(); cc ++ )
  1249. // {
  1250. // std::cout << "File: " << files[cc] << std::endl;
  1251. // }
  1252. std::map<std::string, cmCTest::tm_VectorOfStrings >::iterator it;
  1253. cmCTest::tm_CoverageMap coverageresults;
  1254. this->StartXML(log);
  1255. log << "<Coverage>\n"
  1256. << "\t<StartDateTime>" << start_time << "</StartDateTime>" << std::endl;
  1257. int total_tested = 0;
  1258. int total_untested = 0;
  1259. for ( it = sourcefiles.begin(); it != sourcefiles.end(); it ++ )
  1260. {
  1261. //std::cerr << "Source file: " << it->first << std::endl;
  1262. cmCTest::tm_VectorOfStrings &gfiles = it->second;
  1263. for ( cc = 0; cc < gfiles.size(); cc ++ )
  1264. {
  1265. //std::cout << "\t" << gfiles[cc] << std::endl;
  1266. std::ifstream ifile(gfiles[cc].c_str());
  1267. if ( !ifile )
  1268. {
  1269. std::cerr << "Cannot open file: " << gfiles[cc].c_str() << std::endl;
  1270. }
  1271. ifile.seekg (0, std::ios::end);
  1272. int length = ifile.tellg();
  1273. ifile.seekg (0, std::ios::beg);
  1274. char *buffer = new char [ length + 1 ];
  1275. ifile.read(buffer, length);
  1276. buffer [length] = 0;
  1277. //std::cout << "Read: " << buffer << std::endl;
  1278. std::vector<cmStdString> lines;
  1279. cmSystemTools::Split(buffer, lines);
  1280. delete [] buffer;
  1281. cmCTest::cmCTestCoverage& cov = coverageresults[it->first];
  1282. std::vector<int>& covlines = cov.m_Lines;
  1283. if ( cov.m_FullPath == "" )
  1284. {
  1285. covlines.insert(covlines.begin(), lines.size(), -1);
  1286. if ( allsourcefiles.find(it->first) != allsourcefiles.end() )
  1287. {
  1288. cov.m_FullPath = allsourcefiles[it->first];
  1289. }
  1290. else if ( allbinaryfiles.find(it->first) != allbinaryfiles.end() )
  1291. {
  1292. cov.m_FullPath = allbinaryfiles[it->first];
  1293. }
  1294. cov.m_AbsolutePath = cov.m_FullPath;
  1295. std::string src_dir = m_DartConfiguration["SourceDirectory"];
  1296. if ( src_dir[src_dir.size()-1] != '/' )
  1297. {
  1298. src_dir = src_dir + "/";
  1299. }
  1300. std::string::size_type spos = cov.m_FullPath.find(src_dir);
  1301. if ( spos == 0 )
  1302. {
  1303. cov.m_FullPath = std::string("./") + cov.m_FullPath.substr(src_dir.size());
  1304. }
  1305. else
  1306. {
  1307. //std::cerr << "Compare -- " << cov.m_FullPath << std::endl;
  1308. //std::cerr << " -- " << src_dir << std::endl;
  1309. cov.m_Show = false;
  1310. continue;
  1311. }
  1312. cov.m_Show = true;
  1313. }
  1314. std::string::size_type kk;
  1315. // std::cerr << "number of lines " << lines.size() << "\n";
  1316. for ( kk = 0; kk < lines.size(); kk ++ )
  1317. {
  1318. std::string& line = lines[kk];
  1319. //std::cerr << line << "\n";
  1320. std::string sub1 = line.substr(0, strlen(" #####"));
  1321. std::string sub2 = line.substr(0, strlen(" ######"));
  1322. int count = atoi(sub2.c_str());
  1323. if ( sub1.compare(" #####") == 0 ||
  1324. sub2.compare(" ######") == 0 )
  1325. {
  1326. if ( covlines[kk] == -1 )
  1327. {
  1328. covlines[kk] = 0;
  1329. }
  1330. cov.m_UnTested ++;
  1331. //std::cout << "Untested - ";
  1332. }
  1333. else if ( count > 0 )
  1334. {
  1335. if ( covlines[kk] == -1 )
  1336. {
  1337. covlines[kk] = 0;
  1338. }
  1339. cov.m_Tested ++;
  1340. covlines[kk] += count;
  1341. //std::cout << "Tested[" << count << "] - ";
  1342. }
  1343. //std::cout << line << std::endl;
  1344. }
  1345. }
  1346. }
  1347. //std::cerr << "Finalizing" << std::endl;
  1348. cmCTest::tm_CoverageMap::iterator cit;
  1349. int ccount = 0;
  1350. std::ofstream cfileoutput;
  1351. int cfileoutputcount = 0;
  1352. char cfileoutputname[100];
  1353. std::string local_start_time = ::CurrentTime();
  1354. std::string local_end_time;
  1355. for ( cit = coverageresults.begin(); cit != coverageresults.end(); cit ++ )
  1356. {
  1357. cmCTest::cmCTestCoverage &cov = cit->second;
  1358. if ( !cov.m_Show )
  1359. {
  1360. continue;
  1361. }
  1362. if ( ccount == 100 )
  1363. {
  1364. local_end_time = ::CurrentTime();
  1365. cfileoutput << "\t<EndDateTime>" << local_end_time << "</EndDateTime>\n"
  1366. << "</CoverageLog>" << std::endl;
  1367. this->EndXML(cfileoutput);
  1368. cfileoutput.close();
  1369. std::cout << "Close file: " << cfileoutputname << std::endl;
  1370. ccount = 0;
  1371. }
  1372. if ( ccount == 0 )
  1373. {
  1374. sprintf(cfileoutputname, "CoverageLog-%d.xml", cfileoutputcount++);
  1375. std::cout << "Open file: " << cfileoutputname << std::endl;
  1376. if (!this->OpenOutputFile(m_CurrentTag, cfileoutputname, cfileoutput))
  1377. {
  1378. std::cerr << "Cannot open log file: " << cfileoutputname << std::endl;
  1379. return 1;
  1380. }
  1381. local_start_time = ::CurrentTime();
  1382. this->StartXML(cfileoutput);
  1383. cfileoutput << "<CoverageLog>\n"
  1384. << "\t<StartDateTime>" << local_start_time << "</StartDateTime>" << std::endl;
  1385. }
  1386. //std::cerr << "Final process of Source file: " << cit->first << std::endl;
  1387. std::ifstream ifile(cov.m_AbsolutePath.c_str());
  1388. if ( !ifile )
  1389. {
  1390. std::cerr << "Cannot open file: " << cov.m_FullPath.c_str() << std::endl;
  1391. }
  1392. ifile.seekg (0, std::ios::end);
  1393. int length = ifile.tellg();
  1394. ifile.seekg (0, std::ios::beg);
  1395. char *buffer = new char [ length + 1 ];
  1396. ifile.read(buffer, length);
  1397. buffer [length] = 0;
  1398. //std::cout << "Read: " << buffer << std::endl;
  1399. std::vector<cmStdString> lines;
  1400. cmSystemTools::Split(buffer, lines);
  1401. delete [] buffer;
  1402. cfileoutput << "\t<File Name=\"" << cit->first << "\" FullPath=\""
  1403. << cov.m_FullPath << "\">\n"
  1404. << "\t\t<Report>" << std::endl;
  1405. for ( cc = 0; cc < lines.size(); cc ++ )
  1406. {
  1407. cfileoutput << "\t\t<Line Number=\""
  1408. << static_cast<int>(cc) << "\" Count=\""
  1409. << cov.m_Lines[cc] << "\">"
  1410. << cmCTest::MakeXMLSafe(lines[cc]) << "</Line>" << std::endl;
  1411. }
  1412. cfileoutput << "\t\t</Report>\n"
  1413. << "\t</File>" << std::endl;
  1414. total_tested += cov.m_Tested;
  1415. total_untested += cov.m_UnTested;
  1416. float cper = 0;
  1417. float cmet = 0;
  1418. if ( total_tested + total_untested > 0 && (cov.m_Tested + cov.m_UnTested) > 0)
  1419. {
  1420. cper = (100 * SAFEDIV(static_cast<float>(cov.m_Tested),
  1421. static_cast<float>(cov.m_Tested + cov.m_UnTested)));
  1422. cmet = ( SAFEDIV(static_cast<float>(cov.m_Tested + 10),
  1423. static_cast<float>(cov.m_Tested + cov.m_UnTested + 10)));
  1424. }
  1425. log << "\t<File Name=\"" << cit->first << "\" FullPath=\"" << cov.m_FullPath
  1426. << "\" Covered=\"" << (cmet>0?"true":"false") << "\">\n"
  1427. << "\t\t<LOCTested>" << cov.m_Tested << "</LOCTested>\n"
  1428. << "\t\t<LOCUnTested>" << cov.m_UnTested << "</LOCUnTested>\n"
  1429. << "\t\t<PercentCoverage>";
  1430. log.setf(std::ios::fixed, std::ios::floatfield);
  1431. log.precision(2);
  1432. log << (cper) << "</PercentCoverage>\n"
  1433. << "\t\t<CoverageMetric>";
  1434. log.setf(std::ios::fixed, std::ios::floatfield);
  1435. log.precision(2);
  1436. log << (cmet) << "</CoverageMetric>\n"
  1437. << "\t</File>" << std::endl;
  1438. ccount ++;
  1439. }
  1440. if ( ccount > 0 )
  1441. {
  1442. local_end_time = ::CurrentTime();
  1443. cfileoutput << "\t<EndDateTime>" << local_end_time << "</EndDateTime>\n"
  1444. << "</CoverageLog>" << std::endl;
  1445. this->EndXML(cfileoutput);
  1446. cfileoutput.close();
  1447. }
  1448. int total_lines = total_tested + total_untested;
  1449. float percent_coverage = 100 * SAFEDIV(static_cast<float>(total_tested),
  1450. static_cast<float>(total_lines));
  1451. if ( total_lines == 0 )
  1452. {
  1453. percent_coverage = 0;
  1454. }
  1455. std::string end_time = ::CurrentTime();
  1456. log << "\t<LOCTested>" << total_tested << "</LOCTested>\n"
  1457. << "\t<LOCUntested>" << total_untested << "</LOCUntested>\n"
  1458. << "\t<LOC>" << total_lines << "</LOC>\n"
  1459. << "\t<PercentCoverage>";
  1460. log.setf(std::ios::fixed, std::ios::floatfield);
  1461. log.precision(2);
  1462. log << (percent_coverage)<< "</PercentCoverage>\n"
  1463. << "\t<EndDateTime>" << end_time << "</EndDateTime>\n"
  1464. << "</Coverage>" << std::endl;
  1465. this->EndXML(log);
  1466. std::cout << "\tCovered LOC: " << total_tested << std::endl
  1467. << "\tNot covered LOC: " << total_untested << std::endl
  1468. << "\tTotal LOC: " << total_lines << std::endl
  1469. << "\tPercentage Coverage: ";
  1470. std::cout.setf(std::ios::fixed, std::ios::floatfield);
  1471. std::cout.precision(2);
  1472. std::cout << (percent_coverage) << "%" << std::endl;
  1473. return 1;
  1474. }
  1475. bool cmCTest::OpenOutputFile(const std::string& path,
  1476. const std::string& name, std::ofstream& stream)
  1477. {
  1478. std::string testingDir = m_ToplevelPath + "/Testing";
  1479. if ( path.size() > 0 )
  1480. {
  1481. testingDir += "/" + path;
  1482. }
  1483. if ( cmSystemTools::FileExists(testingDir.c_str()) )
  1484. {
  1485. if ( !cmSystemTools::FileIsDirectory(testingDir.c_str()) )
  1486. {
  1487. std::cerr << "File " << testingDir
  1488. << " is in the place of the testing directory"
  1489. << std::endl;
  1490. return false;
  1491. }
  1492. }
  1493. else
  1494. {
  1495. if ( !cmSystemTools::MakeDirectory(testingDir.c_str()) )
  1496. {
  1497. std::cerr << "Cannot create directory " << testingDir
  1498. << std::endl;
  1499. return false;
  1500. }
  1501. }
  1502. std::string filename = testingDir + "/" + name;
  1503. stream.open(filename.c_str());
  1504. if( !stream )
  1505. {
  1506. std::cerr << "Problem opening file: " << filename << std::endl;
  1507. return false;
  1508. }
  1509. return true;
  1510. }
  1511. void cmCTest::GenerateDartBuildOutput(std::ostream& os,
  1512. std::vector<cmCTestBuildErrorWarning> ew)
  1513. {
  1514. this->StartXML(os);
  1515. os << "<Build>\n"
  1516. << "\t<StartDateTime>" << m_StartBuild << "</StartDateTime>\n"
  1517. << "<BuildCommand>"
  1518. << this->MakeXMLSafe(m_DartConfiguration["MakeCommand"])
  1519. << "</BuildCommand>" << std::endl;
  1520. std::vector<cmCTestBuildErrorWarning>::iterator it;
  1521. for ( it = ew.begin(); it != ew.end(); it++ )
  1522. {
  1523. cmCTestBuildErrorWarning *cm = &(*it);
  1524. os << "\t<" << (cm->m_Error ? "Error" : "Warning") << ">\n"
  1525. << "\t\t<BuildLogLine>" << cm->m_LogLine << "</BuildLogLine>\n"
  1526. << "\t\t<Text>" << this->MakeXMLSafe(cm->m_Text)
  1527. << "\n</Text>" << std::endl;
  1528. if ( cm->m_SourceFile.size() > 0 )
  1529. {
  1530. os << "\t\t<SourceFile>" << cm->m_SourceFile << "</SourceFile>"
  1531. << std::endl;
  1532. }
  1533. if ( cm->m_SourceFileTail.size() > 0 )
  1534. {
  1535. os << "\t\t<SourceFileTail>" << cm->m_SourceFileTail
  1536. << "</SourceFileTail>" << std::endl;
  1537. }
  1538. if ( cm->m_LineNumber >= 0 )
  1539. {
  1540. os << "\t\t<SourceLineNumber>" << cm->m_LineNumber
  1541. << "</SourceLineNumber>" << std::endl;
  1542. }
  1543. os << "\t\t<PreContext>" << this->MakeXMLSafe(cm->m_PreContext)
  1544. << "</PreContext>\n"
  1545. << "\t\t<PostContext>" << this->MakeXMLSafe(cm->m_PostContext)
  1546. << "</PostContext>\n"
  1547. << "\t\t<RepeatCount>0</RepeatCount>\n"
  1548. << "</" << (cm->m_Error ? "Error" : "Warning") << ">\n\n"
  1549. << std::endl;
  1550. }
  1551. os << "\t<Log Encoding=\"base64\" Compression=\"/bin/gzip\">\n\t</Log>\n"
  1552. << "\t<EndDateTime>" << m_EndBuild << "</EndDateTime>\n"
  1553. << "</Build>" << std::endl;
  1554. this->EndXML(os);
  1555. }
  1556. void cmCTest::ProcessDirectory(cmCTest::tm_VectorOfStrings &passed,
  1557. cmCTest::tm_VectorOfStrings &failed,
  1558. bool memcheck)
  1559. {
  1560. // does the DartTestfile.txt exist ?
  1561. if(!cmSystemTools::FileExists("DartTestfile.txt"))
  1562. {
  1563. return;
  1564. }
  1565. // parse the file
  1566. std::ifstream fin("DartTestfile.txt");
  1567. if(!fin)
  1568. {
  1569. return;
  1570. }
  1571. int firstTest = 1;
  1572. cmsys::RegularExpression ireg(this->m_IncludeRegExp.c_str());
  1573. cmsys::RegularExpression ereg(this->m_ExcludeRegExp.c_str());
  1574. cmsys::RegularExpression dartStuff("(<DartMeasurement.*/DartMeasurement[a-zA-Z]*>)");
  1575. cmListFileCache cache;
  1576. cmListFile* listFile = cache.GetFileCache("DartTestfile.txt", false);
  1577. for(std::vector<cmListFileFunction>::const_iterator f =
  1578. listFile->m_Functions.begin(); f != listFile->m_Functions.end(); ++f)
  1579. {
  1580. const cmListFileFunction& lff = *f;
  1581. const std::string& name = lff.m_Name;
  1582. const std::vector<cmListFileArgument>& args = lff.m_Arguments;
  1583. if (name == "SUBDIRS")
  1584. {
  1585. std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
  1586. for(std::vector<cmListFileArgument>::const_iterator j = args.begin();
  1587. j != args.end(); ++j)
  1588. {
  1589. std::string nwd = cwd + "/";
  1590. nwd += j->Value;
  1591. if (cmSystemTools::FileIsDirectory(nwd.c_str()))
  1592. {
  1593. cmSystemTools::ChangeDirectory(nwd.c_str());
  1594. this->ProcessDirectory(passed, failed, memcheck);
  1595. }
  1596. }
  1597. // return to the original directory
  1598. cmSystemTools::ChangeDirectory(cwd.c_str());
  1599. }
  1600. if (name == "ADD_TEST")
  1601. {
  1602. if (this->m_UseExcludeRegExp &&
  1603. this->m_UseExcludeRegExpFirst &&
  1604. ereg.find(args[0].Value.c_str()))
  1605. {
  1606. continue;
  1607. }
  1608. if (this->m_UseIncludeRegExp && !ireg.find(args[0].Value.c_str()))
  1609. {
  1610. continue;
  1611. }
  1612. if (this->m_UseExcludeRegExp &&
  1613. !this->m_UseExcludeRegExpFirst &&
  1614. ereg.find(args[0].Value.c_str()))
  1615. {
  1616. continue;
  1617. }
  1618. cmCTestTestResult cres;
  1619. cres.m_Status = cmCTest::NOT_RUN;
  1620. if (firstTest)
  1621. {
  1622. std::string nwd = cmSystemTools::GetCurrentWorkingDirectory();
  1623. if ( m_Verbose )
  1624. {
  1625. std::cerr << "Changing directory into " << nwd.c_str() << "\n";
  1626. }
  1627. firstTest = 0;
  1628. }
  1629. cres.m_Name = args[0].Value;
  1630. if ( m_ShowOnly )
  1631. {
  1632. std::cout << args[0].Value << std::endl;
  1633. }
  1634. else
  1635. {
  1636. fprintf(stderr,"Testing %-30s ",args[0].Value.c_str());
  1637. fflush(stderr);
  1638. }
  1639. //std::cerr << "Testing " << args[0] << " ... ";
  1640. // find the test executable
  1641. std::string actualCommand = this->FindTheExecutable(args[1].Value.c_str());
  1642. std::string testCommand = cmSystemTools::ConvertToOutputPath(actualCommand.c_str());
  1643. std::string memcheckcommand = "";
  1644. // continue if we did not find the executable
  1645. if (testCommand == "")
  1646. {
  1647. std::cerr << "Unable to find executable: " <<
  1648. args[1].Value.c_str() << "\n";
  1649. m_TestResults.push_back( cres );
  1650. continue;
  1651. }
  1652. // add the arguments
  1653. std::vector<cmListFileArgument>::const_iterator j = args.begin();
  1654. ++j;
  1655. ++j;
  1656. std::vector<const char*> arguments;
  1657. if ( memcheck )
  1658. {
  1659. cmCTest::tm_VectorOfStrings::size_type pp;
  1660. arguments.push_back(m_MemoryTester.c_str());
  1661. memcheckcommand = m_MemoryTester;
  1662. for ( pp = 0; pp < m_MemoryTesterOptionsParsed.size(); pp ++ )
  1663. {
  1664. arguments.push_back(m_MemoryTesterOptionsParsed[pp].c_str());
  1665. memcheckcommand += " ";
  1666. memcheckcommand += cmSystemTools::EscapeSpaces(m_MemoryTesterOptionsParsed[pp].c_str());
  1667. }
  1668. }
  1669. arguments.push_back(actualCommand.c_str());
  1670. for(;j != args.end(); ++j)
  1671. {
  1672. testCommand += " ";
  1673. testCommand += cmSystemTools::EscapeSpaces(j->Value.c_str());
  1674. arguments.push_back(j->Value.c_str());
  1675. }
  1676. arguments.push_back(0);
  1677. /**
  1678. * Run an executable command and put the stdout in output.
  1679. */
  1680. std::string output;
  1681. int retVal = 0;
  1682. double clock_start, clock_finish;
  1683. clock_start = cmSystemTools::GetTime();
  1684. if ( m_Verbose )
  1685. {
  1686. std::cout << std::endl << (memcheck?"MemCheck":"Test") << " command: " << testCommand << std::endl;
  1687. if ( memcheck )
  1688. {
  1689. std::cout << "Memory check command: " << memcheckcommand << std::endl;
  1690. }
  1691. }
  1692. int res = 0;
  1693. if ( !m_ShowOnly )
  1694. {
  1695. res = this->RunTest(arguments, &output, &retVal);
  1696. }
  1697. clock_finish = cmSystemTools::GetTime();
  1698. cres.m_ExecutionTime = (double)(clock_finish - clock_start);
  1699. cres.m_FullCommandLine = testCommand;
  1700. if ( !m_ShowOnly )
  1701. {
  1702. if (res == cmsysProcess_State_Exited && retVal == 0)
  1703. {
  1704. fprintf(stderr," Passed\n");
  1705. passed.push_back(args[0].Value);
  1706. cres.m_Status = cmCTest::COMPLETED;
  1707. }
  1708. else
  1709. {
  1710. cres.m_Status = cmCTest::FAILED;
  1711. if ( res == cmsysProcess_State_Expired )
  1712. {
  1713. fprintf(stderr,"***Timeout\n");
  1714. cres.m_Status = cmCTest::TIMEOUT;
  1715. }
  1716. else if ( res == cmsysProcess_State_Exception )
  1717. {
  1718. fprintf(stderr,"***Exception: ");
  1719. switch ( retVal )
  1720. {
  1721. case cmsysProcess_Exception_Fault:
  1722. fprintf(stderr,"SegFault");
  1723. cres.m_Status = cmCTest::SEGFAULT;
  1724. break;
  1725. case cmsysProcess_Exception_Illegal:
  1726. fprintf(stderr,"Illegal");
  1727. cres.m_Status = cmCTest::ILLEGAL;
  1728. break;
  1729. case cmsysProcess_Exception_Interrupt:
  1730. fprintf(stderr,"Interrupt");
  1731. cres.m_Status = cmCTest::INTERRUPT;
  1732. break;
  1733. case cmsysProcess_Exception_Numerical:
  1734. fprintf(stderr,"Numerical");
  1735. cres.m_Status = cmCTest::NUMERICAL;
  1736. break;
  1737. default:
  1738. fprintf(stderr,"Other");
  1739. cres.m_Status = cmCTest::OTHER_FAULT;
  1740. }
  1741. fprintf(stderr,"\n");
  1742. }
  1743. else if ( res == cmsysProcess_State_Error )
  1744. {
  1745. fprintf(stderr,"***Bad command\n");
  1746. cres.m_Status = cmCTest::BAD_COMMAND;
  1747. }
  1748. else
  1749. {
  1750. fprintf(stderr,"***Failed\n");
  1751. }
  1752. failed.push_back(args[0].Value);
  1753. }
  1754. if (output != "")
  1755. {
  1756. if (dartStuff.find(output.c_str()))
  1757. {
  1758. std::string dartString = dartStuff.match(1);
  1759. cmSystemTools::ReplaceString(output, dartString.c_str(),"");
  1760. cres.m_RegressionImages = this->GenerateRegressionImages(dartString);
  1761. }
  1762. }
  1763. }
  1764. cres.m_Output = output;
  1765. cres.m_ReturnValue = retVal;
  1766. std::string nwd = cmSystemTools::GetCurrentWorkingDirectory();
  1767. if ( nwd.size() > m_ToplevelPath.size() )
  1768. {
  1769. nwd = "." + nwd.substr(m_ToplevelPath.size(), nwd.npos);
  1770. }
  1771. cmSystemTools::ReplaceString(nwd, "\\", "/");
  1772. cres.m_Path = nwd;
  1773. cres.m_CompletionStatus = "Completed";
  1774. m_TestResults.push_back( cres );
  1775. }
  1776. }
  1777. }
  1778. bool cmCTest::InitializeMemoryChecking()
  1779. {
  1780. // Setup the command
  1781. if ( cmSystemTools::FileExists(m_DartConfiguration["MemoryCheckCommand"].c_str()) )
  1782. {
  1783. m_MemoryTester
  1784. = cmSystemTools::ConvertToOutputPath(m_DartConfiguration["MemoryCheckCommand"].c_str());
  1785. }
  1786. else if ( cmSystemTools::FileExists(m_DartConfiguration["PurifyCommand"].c_str()) )
  1787. {
  1788. m_MemoryTester
  1789. = cmSystemTools::ConvertToOutputPath(m_DartConfiguration["PurifyCommand"].c_str());
  1790. }
  1791. else if ( cmSystemTools::FileExists(m_DartConfiguration["ValgrindCommand"].c_str()) )
  1792. {
  1793. m_MemoryTester
  1794. = cmSystemTools::ConvertToOutputPath(m_DartConfiguration["ValgrindCommand"].c_str());
  1795. }
  1796. else
  1797. {
  1798. std::cerr << "Memory checker (MemoryCheckCommand) not set, or cannot find the specified program."
  1799. << std::endl;
  1800. return false;
  1801. }
  1802. if ( m_MemoryTester[0] == '\"' && m_MemoryTester[m_MemoryTester.size()-1] == '\"' )
  1803. {
  1804. m_MemoryTester = m_MemoryTester.substr(1, m_MemoryTester.size()-2);
  1805. }
  1806. // Setup the options
  1807. if ( m_DartConfiguration["MemoryCheckCommandOptions"].size() )
  1808. {
  1809. m_MemoryTesterOptions = m_DartConfiguration["MemoryCheckCommandOptions"];
  1810. }
  1811. else if ( m_DartConfiguration["ValgrindCommandOptions"].size() )
  1812. {
  1813. m_MemoryTesterOptions = m_DartConfiguration["ValgrindCommandOptions"];
  1814. }
  1815. m_MemoryTesterOutputFile = m_ToplevelPath + "/Testing/Temporary/MemoryChecker.log";
  1816. m_MemoryTesterOutputFile = cmSystemTools::EscapeSpaces(m_MemoryTesterOutputFile.c_str());
  1817. if ( m_MemoryTester.find("valgrind") != std::string::npos )
  1818. {
  1819. m_MemoryTesterStyle = cmCTest::VALGRIND;
  1820. if ( !m_MemoryTesterOptions.size() )
  1821. {
  1822. m_MemoryTesterOptions = "-q --skin=memcheck --leak-check=yes --show-reachable=yes --workaround-gcc296-bugs=yes --num-callers=100";
  1823. }
  1824. if ( m_DartConfiguration["MemoryCheckSuppressionFile"].size() )
  1825. {
  1826. if ( !cmSystemTools::FileExists(m_DartConfiguration["MemoryCheckSuppressionFile"].c_str()) )
  1827. {
  1828. std::cerr << "Cannot find memory checker suppression file: "
  1829. << m_DartConfiguration["MemoryCheckSuppressionFile"].c_str() << std::endl;
  1830. return false;
  1831. }
  1832. m_MemoryTesterOptions += " --suppressions=" + cmSystemTools::EscapeSpaces(m_DartConfiguration["MemoryCheckSuppressionFile"].c_str()) + "";
  1833. }
  1834. }
  1835. else if ( m_MemoryTester.find("purify") != std::string::npos )
  1836. {
  1837. m_MemoryTesterStyle = cmCTest::PURIFY;
  1838. #ifdef _WIN32
  1839. m_MemoryTesterOptions += " /SAVETEXTDATA=" + m_MemoryTesterOutputFile;
  1840. #else
  1841. m_MemoryTesterOptions += " -log-file=" + m_MemoryTesterOutputFile;
  1842. #endif
  1843. }
  1844. else if ( m_MemoryTester.find("boundschecker") != std::string::npos )
  1845. {
  1846. m_MemoryTesterStyle = cmCTest::BOUNDS_CHECKER;
  1847. std::cerr << "Bounds checker not yet implemented" << std::endl;
  1848. return false;
  1849. }
  1850. else
  1851. {
  1852. std::cerr << "Do not understand memory checker: " << m_MemoryTester.c_str() << std::endl;
  1853. return false;
  1854. }
  1855. m_MemoryTesterOptionsParsed = cmSystemTools::ParseArguments(m_MemoryTesterOptions.c_str());
  1856. cmCTest::tm_VectorOfStrings::size_type cc;
  1857. for ( cc = 0; cmCTestMemCheckResultStrings[cc]; cc ++ )
  1858. {
  1859. m_MemoryTesterGlobalResults[cc] = 0;
  1860. }
  1861. return true;
  1862. }
  1863. int cmCTest::TestDirectory(bool memcheck)
  1864. {
  1865. std::cout << (memcheck ? "Memory check" : "Test") << " project" << std::endl;
  1866. if ( memcheck )
  1867. {
  1868. if ( !this->InitializeMemoryChecking() )
  1869. {
  1870. return 1;
  1871. }
  1872. }
  1873. cmCTest::tm_VectorOfStrings passed;
  1874. cmCTest::tm_VectorOfStrings failed;
  1875. int total;
  1876. m_StartTest = ::CurrentTime();
  1877. this->ProcessDirectory(passed, failed, memcheck);
  1878. m_EndTest = ::CurrentTime();
  1879. total = int(passed.size()) + int(failed.size());
  1880. if (total == 0)
  1881. {
  1882. if ( !m_ShowOnly )
  1883. {
  1884. std::cerr << "No tests were found!!!\n";
  1885. }
  1886. }
  1887. else
  1888. {
  1889. if (m_Verbose && passed.size() &&
  1890. (m_UseIncludeRegExp || m_UseExcludeRegExp))
  1891. {
  1892. std::cerr << "\nThe following tests passed:\n";
  1893. for(cmCTest::tm_VectorOfStrings::iterator j = passed.begin();
  1894. j != passed.end(); ++j)
  1895. {
  1896. std::cerr << "\t" << *j << "\n";
  1897. }
  1898. }
  1899. float percent = float(passed.size()) * 100.0f / total;
  1900. fprintf(stderr,"\n%.0f%% tests passed, %i tests failed out of %i\n",
  1901. percent, int(failed.size()), total);
  1902. if (failed.size())
  1903. {
  1904. std::cerr << "\nThe following tests FAILED:\n";
  1905. for(cmCTest::tm_VectorOfStrings::iterator j = failed.begin();
  1906. j != failed.end(); ++j)
  1907. {
  1908. std::cerr << "\t" << *j << "\n";
  1909. }
  1910. }
  1911. }
  1912. if ( m_DartMode )
  1913. {
  1914. std::ofstream ofs;
  1915. if( !this->OpenOutputFile(m_CurrentTag,
  1916. (memcheck ? (m_CompatibilityMode?"Purify.xml":"MemCheck.xml") : "Test.xml"), ofs) )
  1917. {
  1918. std::cerr << "Cannot create " << (memcheck ? "memory check" : "testing")
  1919. << " XML file" << std::endl;
  1920. return 1;
  1921. }
  1922. if ( memcheck )
  1923. {
  1924. this->GenerateDartMemCheckOutput(ofs);
  1925. }
  1926. else
  1927. {
  1928. this->GenerateDartTestOutput(ofs);
  1929. }
  1930. }
  1931. return int(failed.size());
  1932. }
  1933. int cmCTest::SubmitResults()
  1934. {
  1935. cmCTest::tm_VectorOfStrings files;
  1936. std::string prefix = this->GetSubmitResultsPrefix();
  1937. // TODO:
  1938. // Check if test is enabled
  1939. if ( this->CTestFileExists("Update.xml") )
  1940. {
  1941. files.push_back("Update.xml");
  1942. }
  1943. if ( this->CTestFileExists("Configure.xml") )
  1944. {
  1945. files.push_back("Configure.xml");
  1946. }
  1947. if ( this->CTestFileExists("Build.xml") )
  1948. {
  1949. files.push_back("Build.xml");
  1950. }
  1951. if ( this->CTestFileExists("Test.xml") )
  1952. {
  1953. files.push_back("Test.xml");
  1954. }
  1955. if ( this->CTestFileExists("Coverage.xml") )
  1956. {
  1957. files.push_back("Coverage.xml");
  1958. cmCTest::tm_VectorOfStrings gfiles;
  1959. std::string gpath = m_ToplevelPath + "/Testing/" + m_CurrentTag;
  1960. std::string::size_type glen = gpath.size() + 1;
  1961. gpath = gpath + "/CoverageLog*";
  1962. //std::cout << "Globbing for: " << gpath.c_str() << std::endl;
  1963. if ( cmSystemTools::SimpleGlob(gpath, gfiles, 1) )
  1964. {
  1965. size_t cc;
  1966. for ( cc = 0; cc < gfiles.size(); cc ++ )
  1967. {
  1968. gfiles[cc] = gfiles[cc].substr(glen);
  1969. //std::cout << "Glob file: " << gfiles[cc].c_str() << std::endl;
  1970. files.push_back(gfiles[cc]);
  1971. }
  1972. }
  1973. else
  1974. {
  1975. std::cerr << "Problem globbing" << std::endl;
  1976. }
  1977. }
  1978. if ( this->CTestFileExists("MemCheck.xml") )
  1979. {
  1980. files.push_back("MemCheck.xml");
  1981. }
  1982. if ( this->CTestFileExists("Purify.xml") )
  1983. {
  1984. files.push_back("Purify.xml");
  1985. }
  1986. cmCTestSubmit submit;
  1987. submit.SetVerbose(m_Verbose);
  1988. if ( m_DartConfiguration["DropMethod"] == "" ||
  1989. m_DartConfiguration["DropMethod"] == "ftp" )
  1990. {
  1991. std::cout << " Using FTP submit method" << std::endl;
  1992. std::string url = "ftp://";
  1993. url += cmCTest::MakeURLSafe(m_DartConfiguration["DropSiteUser"]) + ":" +
  1994. cmCTest::MakeURLSafe(m_DartConfiguration["DropSitePassword"]) + "@" +
  1995. m_DartConfiguration["DropSite"] +
  1996. cmCTest::MakeURLSafe(m_DartConfiguration["DropLocation"]);
  1997. if ( !submit.SubmitUsingFTP(m_ToplevelPath+"/Testing/"+m_CurrentTag,
  1998. files, prefix, url) )
  1999. {
  2000. std::cerr << " Problems when submitting via FTP" << std::endl;
  2001. return 0;
  2002. }
  2003. if ( !submit.TriggerUsingHTTP(files, prefix, m_DartConfiguration["TriggerSite"]) )
  2004. {
  2005. std::cerr << " Problems when triggering via HTTP" << std::endl;
  2006. return 0;
  2007. }
  2008. std::cout << " Submission successfull" << std::endl;
  2009. return 1;
  2010. }
  2011. else if ( m_DartConfiguration["DropMethod"] == "http" )
  2012. {
  2013. std::cout << " Using HTTP submit method" << std::endl;
  2014. std::string url = "http://";
  2015. if ( m_DartConfiguration["DropSiteUser"].size() > 0 )
  2016. {
  2017. url += m_DartConfiguration["DropSiteUser"];
  2018. if ( m_DartConfiguration["DropSitePassword"].size() > 0 )
  2019. {
  2020. url += ":" + m_DartConfiguration["DropSitePassword"];
  2021. }
  2022. url += "@";
  2023. }
  2024. url += m_DartConfiguration["DropSite"] + m_DartConfiguration["DropLocation"];
  2025. if ( !submit.SubmitUsingHTTP(m_ToplevelPath+"/Testing/"+m_CurrentTag, files, prefix, url) )
  2026. {
  2027. std::cerr << " Problems when submitting via HTTP" << std::endl;
  2028. return 0;
  2029. }
  2030. if ( !submit.TriggerUsingHTTP(files, prefix, m_DartConfiguration["TriggerSite"]) )
  2031. {
  2032. std::cerr << " Problems when triggering via HTTP" << std::endl;
  2033. return 0;
  2034. }
  2035. std::cout << " Submission successfull" << std::endl;
  2036. return 1;
  2037. }
  2038. else
  2039. {
  2040. std::cerr << "SCP submit not yet implemented" << std::endl;
  2041. }
  2042. return 0;
  2043. }
  2044. bool cmCTest::CTestFileExists(const std::string& filename)
  2045. {
  2046. std::string testingDir = m_ToplevelPath + "/Testing/" + m_CurrentTag + "/" +
  2047. filename;
  2048. return cmSystemTools::FileExists(testingDir.c_str());
  2049. }
  2050. std::string cmCTest::GetSubmitResultsPrefix()
  2051. {
  2052. std::string name = m_DartConfiguration["Site"] +
  2053. "___" + m_DartConfiguration["BuildName"] +
  2054. "___" + m_CurrentTag + "-" +
  2055. this->GetTestModelString() + "___XML___";
  2056. return name;
  2057. }
  2058. void cmCTest::GenerateDartMemCheckOutput(std::ostream& os)
  2059. {
  2060. if ( !m_DartMode )
  2061. {
  2062. return;
  2063. }
  2064. this->StartXML(os);
  2065. if ( m_CompatibilityMode )
  2066. {
  2067. os << "<Purify>" << std::endl;
  2068. }
  2069. else
  2070. {
  2071. os << "<MemCheck>" << std::endl;
  2072. }
  2073. os << "\t<StartDateTime>" << m_StartTest << "</StartDateTime>\n"
  2074. << "\t<TestList>\n";
  2075. tm_TestResultsVector::size_type cc;
  2076. for ( cc = 0; cc < m_TestResults.size(); cc ++ )
  2077. {
  2078. cmCTestTestResult *result = &m_TestResults[cc];
  2079. os << "\t\t<Test>" << this->MakeXMLSafe(result->m_Path)
  2080. << "/" << this->MakeXMLSafe(result->m_Name)
  2081. << "</Test>" << std::endl;
  2082. }
  2083. os << "\t</TestList>\n";
  2084. for ( cc = 0; cc < m_TestResults.size(); cc ++ )
  2085. {
  2086. cmCTestTestResult *result = &m_TestResults[cc];
  2087. std::string memcheckstr;
  2088. int memcheckresults[cmCTest::NO_MEMORY_FAULT];
  2089. int kk;
  2090. this->ProcessMemCheckOutput(result->m_Output, memcheckstr, memcheckresults);
  2091. os << "\t<Test Status=\"";
  2092. if ( result->m_Status == cmCTest::COMPLETED )
  2093. {
  2094. os << "passed";
  2095. }
  2096. else if ( result->m_Status == cmCTest::NOT_RUN )
  2097. {
  2098. os << "notrun";
  2099. }
  2100. else
  2101. {
  2102. os << "failed";
  2103. }
  2104. os << "\">\n"
  2105. << "\t\t<Name>" << this->MakeXMLSafe(result->m_Name) << "</Name>\n"
  2106. << "\t\t<Path>" << this->MakeXMLSafe(result->m_Path) << "</Path>\n"
  2107. << "\t\t<FullName>" << this->MakeXMLSafe(result->m_Path)
  2108. << "/" << this->MakeXMLSafe(result->m_Name) << "</FullName>\n"
  2109. << "\t\t<FullCommandLine>"
  2110. << this->MakeXMLSafe(result->m_FullCommandLine)
  2111. << "</FullCommandLine>\n"
  2112. << "\t\t<Results>" << std::endl;
  2113. for ( kk = 0; cmCTestMemCheckResultStrings[kk]; kk ++ )
  2114. {
  2115. os << "\t\t\t<" << cmCTestMemCheckResultStrings[kk] << ">"
  2116. << memcheckresults[kk]
  2117. << "</" << cmCTestMemCheckResultStrings[kk] << ">" << std::endl;
  2118. m_MemoryTesterGlobalResults[kk] += memcheckresults[kk];
  2119. }
  2120. os
  2121. << "\t\t</Results>\n"
  2122. << "\t<Log>\n" << memcheckstr << std::endl
  2123. << "\t</Log>\n"
  2124. << "\t</Test>" << std::endl;
  2125. }
  2126. os << "\t<EndDateTime>" << m_EndTest << "</EndDateTime>" << std::endl;
  2127. if ( m_CompatibilityMode )
  2128. {
  2129. os << "</Purify>" << std::endl;
  2130. }
  2131. else
  2132. {
  2133. os << "</MemCheck>" << std::endl;
  2134. }
  2135. this->EndXML(os);
  2136. std::cerr << "Memory checking results:" << std::endl;
  2137. for ( cc = 0; cmCTestMemCheckResultStrings[cc]; cc ++ )
  2138. {
  2139. std::cerr << "\t\t" << cmCTestMemCheckResultStrings[cc] << " - "
  2140. << m_MemoryTesterGlobalResults[cc] << std::endl;
  2141. }
  2142. }
  2143. void cmCTest::GenerateDartTestOutput(std::ostream& os)
  2144. {
  2145. if ( !m_DartMode )
  2146. {
  2147. return;
  2148. }
  2149. this->StartXML(os);
  2150. os << "<Testing>\n"
  2151. << "\t<StartDateTime>" << m_StartTest << "</StartDateTime>\n"
  2152. << "\t<TestList>\n";
  2153. tm_TestResultsVector::size_type cc;
  2154. for ( cc = 0; cc < m_TestResults.size(); cc ++ )
  2155. {
  2156. cmCTestTestResult *result = &m_TestResults[cc];
  2157. os << "\t\t<Test>" << this->MakeXMLSafe(result->m_Path)
  2158. << "/" << this->MakeXMLSafe(result->m_Name)
  2159. << "</Test>" << std::endl;
  2160. }
  2161. os << "\t</TestList>\n";
  2162. for ( cc = 0; cc < m_TestResults.size(); cc ++ )
  2163. {
  2164. cmCTestTestResult *result = &m_TestResults[cc];
  2165. os << "\t<Test Status=\"";
  2166. if ( result->m_Status == cmCTest::COMPLETED )
  2167. {
  2168. os << "passed";
  2169. }
  2170. else if ( result->m_Status == cmCTest::NOT_RUN )
  2171. {
  2172. os << "notrun";
  2173. }
  2174. else
  2175. {
  2176. os << "failed";
  2177. }
  2178. os << "\">\n"
  2179. << "\t\t<Name>" << this->MakeXMLSafe(result->m_Name) << "</Name>\n"
  2180. << "\t\t<Path>" << this->MakeXMLSafe(result->m_Path) << "</Path>\n"
  2181. << "\t\t<FullName>" << this->MakeXMLSafe(result->m_Path)
  2182. << "/" << this->MakeXMLSafe(result->m_Name) << "</FullName>\n"
  2183. << "\t\t<FullCommandLine>"
  2184. << this->MakeXMLSafe(result->m_FullCommandLine)
  2185. << "</FullCommandLine>\n"
  2186. << "\t\t<Results>" << std::endl;
  2187. if ( result->m_Status != cmCTest::NOT_RUN )
  2188. {
  2189. if ( result->m_Status != cmCTest::COMPLETED || result->m_ReturnValue )
  2190. {
  2191. os << "\t\t\t<NamedMeasurement type=\"text/string\" name=\"Exit Code\"><Value>"
  2192. << this->GetTestStatus(result->m_Status) << "</Value></NamedMeasurement>\n"
  2193. << "\t\t\t<NamedMeasurement type=\"text/string\" name=\"Exit Value\"><Value>"
  2194. << result->m_ReturnValue << "</Value></NamedMeasurement>" << std::endl;
  2195. }
  2196. os << result->m_RegressionImages;
  2197. os << "\t\t\t<NamedMeasurement type=\"numeric/double\" "
  2198. << "name=\"Execution Time\"><Value>"
  2199. << result->m_ExecutionTime << "</Value></NamedMeasurement>\n";
  2200. os
  2201. << "\t\t\t<NamedMeasurement type=\"text/string\" "
  2202. << "name=\"Completion Status\"><Value>"
  2203. << result->m_CompletionStatus << "</Value></NamedMeasurement>\n";
  2204. }
  2205. os
  2206. << "\t\t\t<Measurement>\n"
  2207. << "\t\t\t\t<Value>" << this->MakeXMLSafe(result->m_Output)
  2208. << "</Value>\n"
  2209. << "\t\t\t</Measurement>\n"
  2210. << "\t\t</Results>\n"
  2211. << "\t</Test>" << std::endl;
  2212. }
  2213. os << "\t<EndDateTime>" << m_EndTest << "</EndDateTime>\n"
  2214. << "</Testing>" << std::endl;
  2215. this->EndXML(os);
  2216. }
  2217. int cmCTest::ProcessTests()
  2218. {
  2219. int res = 0;
  2220. bool notest = true;
  2221. int cc;
  2222. int update_count = 0;
  2223. for ( cc = 0; cc < LAST_TEST; cc ++ )
  2224. {
  2225. if ( m_Tests[cc] )
  2226. {
  2227. notest = false;
  2228. break;
  2229. }
  2230. }
  2231. if ( m_Tests[UPDATE_TEST] || m_Tests[ALL_TEST] )
  2232. {
  2233. update_count = this->UpdateDirectory();
  2234. if ( update_count < 0 )
  2235. {
  2236. res += 1;
  2237. }
  2238. }
  2239. if ( m_TestModel == cmCTest::CONTINUOUS && !update_count )
  2240. {
  2241. return 0;
  2242. }
  2243. if ( m_Tests[CONFIGURE_TEST] || m_Tests[ALL_TEST] )
  2244. {
  2245. res += this->ConfigureDirectory();
  2246. }
  2247. if ( m_Tests[BUILD_TEST] || m_Tests[ALL_TEST] )
  2248. {
  2249. res += this->BuildDirectory();
  2250. }
  2251. if ( m_Tests[TEST_TEST] || m_Tests[ALL_TEST] || notest )
  2252. {
  2253. res += this->TestDirectory(false);
  2254. }
  2255. if ( m_Tests[COVERAGE_TEST] || m_Tests[ALL_TEST] )
  2256. {
  2257. this->CoverageDirectory();
  2258. }
  2259. if ( m_Tests[MEMCHECK_TEST] || m_Tests[ALL_TEST] )
  2260. {
  2261. res += this->TestDirectory(true);
  2262. }
  2263. if ( m_Tests[SUBMIT_TEST] || m_Tests[ALL_TEST] )
  2264. {
  2265. this->SubmitResults();
  2266. }
  2267. return res;
  2268. }
  2269. std::string cmCTest::GetTestModelString()
  2270. {
  2271. switch ( m_TestModel )
  2272. {
  2273. case cmCTest::NIGHTLY:
  2274. return "Nightly";
  2275. case cmCTest::CONTINUOUS:
  2276. return "Continuous";
  2277. }
  2278. return "Experimental";
  2279. }
  2280. #define SPACE_REGEX "[ \t\r\n]"
  2281. std::string cmCTest::GenerateRegressionImages(const std::string& xml)
  2282. {
  2283. cmsys::RegularExpression twoattributes(
  2284. "<DartMeasurement"
  2285. SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\""
  2286. SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\""
  2287. SPACE_REGEX "*>([^<]*)</DartMeasurement>");
  2288. cmsys::RegularExpression threeattributes(
  2289. "<DartMeasurement"
  2290. SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\""
  2291. SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\""
  2292. SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\""
  2293. SPACE_REGEX "*>([^<]*)</DartMeasurement>");
  2294. cmsys::RegularExpression fourattributes(
  2295. "<DartMeasurement"
  2296. SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\""
  2297. SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\""
  2298. SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\""
  2299. SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\""
  2300. SPACE_REGEX "*>([^<]*)</DartMeasurement>");
  2301. cmsys::RegularExpression measurementfile(
  2302. "<DartMeasurementFile"
  2303. SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\""
  2304. SPACE_REGEX "*(name|type|encoding|compression)=\"([^\"]*)\""
  2305. SPACE_REGEX "*>([^<]*)</DartMeasurementFile>");
  2306. cmOStringStream ostr;
  2307. bool done = false;
  2308. std::string cxml = xml;
  2309. while ( ! done )
  2310. {
  2311. if ( twoattributes.find(cxml) )
  2312. {
  2313. ostr
  2314. << "\t\t\t<NamedMeasurement"
  2315. << " " << twoattributes.match(1) << "=\"" << twoattributes.match(2) << "\""
  2316. << " " << twoattributes.match(3) << "=\"" << twoattributes.match(4) << "\""
  2317. << "><Value>" << twoattributes.match(5)
  2318. << "</Value></NamedMeasurement>"
  2319. << std::endl;
  2320. cxml.erase(twoattributes.start(), twoattributes.end() - twoattributes.start());
  2321. }
  2322. else if ( threeattributes.find(cxml) )
  2323. {
  2324. ostr
  2325. << "\t\t\t<NamedMeasurement"
  2326. << " " << threeattributes.match(1) << "=\"" << threeattributes.match(2) << "\""
  2327. << " " << threeattributes.match(3) << "=\"" << threeattributes.match(4) << "\""
  2328. << " " << threeattributes.match(5) << "=\"" << threeattributes.match(6) << "\""
  2329. << "><Value>" << threeattributes.match(7)
  2330. << "</Value></NamedMeasurement>"
  2331. << std::endl;
  2332. cxml.erase(threeattributes.start(), threeattributes.end() - threeattributes.start());
  2333. }
  2334. else if ( fourattributes.find(cxml) )
  2335. {
  2336. ostr
  2337. << "\t\t\t<NamedMeasurement"
  2338. << " " << fourattributes.match(1) << "=\"" << fourattributes.match(2) << "\""
  2339. << " " << fourattributes.match(3) << "=\"" << fourattributes.match(4) << "\""
  2340. << " " << fourattributes.match(5) << "=\"" << fourattributes.match(6) << "\""
  2341. << " " << fourattributes.match(7) << "=\"" << fourattributes.match(8) << "\""
  2342. << "><Value>" << fourattributes.match(9)
  2343. << "</Value></NamedMeasurement>"
  2344. << std::endl;
  2345. cxml.erase(fourattributes.start(), fourattributes.end() - fourattributes.start());
  2346. }
  2347. else if ( measurementfile.find(cxml) )
  2348. {
  2349. const std::string& filename = measurementfile.match(5);
  2350. if ( cmSystemTools::FileExists(filename.c_str()) )
  2351. {
  2352. long len = cmSystemTools::FileLength(filename.c_str());
  2353. std::ifstream ifs(filename.c_str(), std::ios::in
  2354. #ifdef _WIN32
  2355. | std::ios::binary
  2356. #endif
  2357. );
  2358. unsigned char *file_buffer = new unsigned char [ len + 1 ];
  2359. ifs.read(reinterpret_cast<char*>(file_buffer), len);
  2360. unsigned char *encoded_buffer = new unsigned char [ static_cast<int>(len * 1.5 + 1) ];
  2361. unsigned long rlen = cmsysBase64_Encode(file_buffer, len, encoded_buffer, 1);
  2362. unsigned long cc;
  2363. ostr
  2364. << "\t\t\t<NamedMeasurement"
  2365. << " " << measurementfile.match(1) << "=\"" << measurementfile.match(2) << "\""
  2366. << " " << measurementfile.match(3) << "=\"" << measurementfile.match(4) << "\""
  2367. << " encoding=\"base64\""
  2368. << ">" << std::endl << "\t\t\t\t<Value>";
  2369. for ( cc = 0; cc < rlen; cc ++ )
  2370. {
  2371. ostr << encoded_buffer[cc];
  2372. if ( cc % 60 == 0 && cc )
  2373. {
  2374. ostr << std::endl;
  2375. }
  2376. }
  2377. ostr
  2378. << "</Value>" << std::endl << "\t\t\t</NamedMeasurement>"
  2379. << std::endl;
  2380. delete [] file_buffer;
  2381. delete [] encoded_buffer;
  2382. }
  2383. else
  2384. {
  2385. int idx = 4;
  2386. if ( measurementfile.match(1) == "name" )
  2387. {
  2388. idx = 2;
  2389. }
  2390. ostr
  2391. << "\t\t\t<NamedMeasurement"
  2392. << " name=\"" << measurementfile.match(idx) << "\""
  2393. << " text=\"text/string\""
  2394. << "><Value>File " << filename << " not found</Value></NamedMeasurement>"
  2395. << std::endl;
  2396. }
  2397. cxml.erase(measurementfile.start(), measurementfile.end() - measurementfile.start());
  2398. }
  2399. else
  2400. {
  2401. done = true;
  2402. }
  2403. }
  2404. return ostr.str();
  2405. }
  2406. int cmCTest::RunMakeCommand(const char* command, std::string* output,
  2407. int* retVal, const char* dir, bool verbose, int timeout, std::ofstream& ofs)
  2408. {
  2409. std::vector<cmStdString> args = cmSystemTools::ParseArguments(command);
  2410. if(args.size() < 1)
  2411. {
  2412. return false;
  2413. }
  2414. std::vector<const char*> argv;
  2415. for(std::vector<cmStdString>::const_iterator a = args.begin();
  2416. a != args.end(); ++a)
  2417. {
  2418. argv.push_back(a->c_str());
  2419. }
  2420. argv.push_back(0);
  2421. if ( output )
  2422. {
  2423. *output = "";
  2424. }
  2425. cmsysProcess* cp = cmsysProcess_New();
  2426. cmsysProcess_SetCommand(cp, &*argv.begin());
  2427. cmsysProcess_SetWorkingDirectory(cp, dir);
  2428. cmsysProcess_SetOption(cp, cmsysProcess_Option_HideWindow, 1);
  2429. cmsysProcess_SetTimeout(cp, timeout);
  2430. cmsysProcess_Execute(cp);
  2431. std::string::size_type tick = 0;
  2432. std::string::size_type tick_len = 1024;
  2433. std::string::size_type tick_line_len = 50;
  2434. char* data;
  2435. int length;
  2436. if ( !verbose )
  2437. {
  2438. std::cout << " Each . represents " << tick_len << " bytes of output" << std::endl;
  2439. std::cout << " " << std::flush;
  2440. }
  2441. while(cmsysProcess_WaitForData(cp, &data, &length, 0))
  2442. {
  2443. if ( output )
  2444. {
  2445. for(int cc =0; cc < length; ++cc)
  2446. {
  2447. if(data[cc] == 0)
  2448. {
  2449. data[cc] = '\n';
  2450. }
  2451. }
  2452. output->append(data, length);
  2453. if ( !verbose )
  2454. {
  2455. while ( output->size() > (tick * tick_len) )
  2456. {
  2457. tick ++;
  2458. std::cout << "." << std::flush;
  2459. if ( tick % tick_line_len == 0 && tick > 0 )
  2460. {
  2461. std::cout << " Size: ";
  2462. std::cout << int((output->size() / 1024.0) + 1) << "K" << std::endl;
  2463. std::cout << " " << std::flush;
  2464. }
  2465. }
  2466. }
  2467. }
  2468. if(verbose)
  2469. {
  2470. std::cout.write(data, length);
  2471. std::cout.flush();
  2472. }
  2473. if ( ofs )
  2474. {
  2475. ofs.write(data, length);
  2476. ofs.flush();
  2477. }
  2478. }
  2479. std::cout << " Size of output: ";
  2480. std::cout << int(output->size() / 1024.0) << "K" << std::endl;
  2481. cmsysProcess_WaitForExit(cp, 0);
  2482. int result = cmsysProcess_GetState(cp);
  2483. if(result == cmsysProcess_State_Exited)
  2484. {
  2485. *retVal = cmsysProcess_GetExitValue(cp);
  2486. }
  2487. else if(result == cmsysProcess_State_Exception)
  2488. {
  2489. *retVal = cmsysProcess_GetExitException(cp);
  2490. std::cout << "There was an exception: " << *retVal << std::endl;
  2491. }
  2492. else if(result == cmsysProcess_State_Expired)
  2493. {
  2494. std::cout << "There was a timeout" << std::endl;
  2495. }
  2496. else if(result == cmsysProcess_State_Error)
  2497. {
  2498. *output += "\n*** ERROR executing: ";
  2499. *output += cmsysProcess_GetErrorString(cp);
  2500. }
  2501. cmsysProcess_Delete(cp);
  2502. return result;
  2503. }
  2504. int cmCTest::RunTest(std::vector<const char*> argv, std::string* output, int *retVal)
  2505. {
  2506. std::vector<char> tempOutput;
  2507. if ( output )
  2508. {
  2509. *output = "";
  2510. }
  2511. cmsysProcess* cp = cmsysProcess_New();
  2512. cmsysProcess_SetCommand(cp, &*argv.begin());
  2513. std::cout << "Command is: " << argv[0] << std::endl;
  2514. if(cmSystemTools::GetRunCommandHideConsole())
  2515. {
  2516. cmsysProcess_SetOption(cp, cmsysProcess_Option_HideWindow, 1);
  2517. }
  2518. cmsysProcess_SetTimeout(cp, m_TimeOut);
  2519. cmsysProcess_Execute(cp);
  2520. char* data;
  2521. int length;
  2522. while(cmsysProcess_WaitForData(cp, &data, &length, 0))
  2523. {
  2524. if ( output )
  2525. {
  2526. tempOutput.insert(tempOutput.end(), data, data+length);
  2527. }
  2528. if ( m_Verbose )
  2529. {
  2530. std::cout.write(data, length);
  2531. std::cout.flush();
  2532. }
  2533. }
  2534. cmsysProcess_WaitForExit(cp, 0);
  2535. if(output)
  2536. {
  2537. output->append(&*tempOutput.begin(), tempOutput.size());
  2538. }
  2539. int result = cmsysProcess_GetState(cp);
  2540. if(result == cmsysProcess_State_Exited)
  2541. {
  2542. *retVal = cmsysProcess_GetExitValue(cp);
  2543. }
  2544. else if(result == cmsysProcess_State_Exception)
  2545. {
  2546. *retVal = cmsysProcess_GetExitException(cp);
  2547. }
  2548. else if(result == cmsysProcess_State_Error)
  2549. {
  2550. std::string outerr = "\n*** ERROR executing: ";
  2551. outerr += cmsysProcess_GetErrorString(cp);
  2552. *output += outerr;
  2553. if ( m_Verbose )
  2554. {
  2555. std::cout << outerr.c_str() << "\n";
  2556. std::cout.flush();
  2557. }
  2558. }
  2559. cmsysProcess_Delete(cp);
  2560. return result;
  2561. }
  2562. const char* cmCTest::GetTestStatus(int status)
  2563. {
  2564. static const char statuses[][100] = {
  2565. "Not Run",
  2566. "Timeout",
  2567. "SEGFAULT",
  2568. "ILLEGAL",
  2569. "INTERRUPT",
  2570. "NUMERICAL",
  2571. "OTHER_FAULT",
  2572. "Failed",
  2573. "BAD_COMMAND",
  2574. "Completed"
  2575. };
  2576. if ( status < cmCTest::NOT_RUN || status > cmCTest::COMPLETED )
  2577. {
  2578. return "No Status";
  2579. }
  2580. return statuses[status];
  2581. }
  2582. void cmCTestRemoveDirectory(const char *binDir)
  2583. {
  2584. cmsys::Directory dir;
  2585. dir.Load(binDir);
  2586. size_t fileNum;
  2587. for (fileNum = 0; fileNum < dir.GetNumberOfFiles(); ++fileNum)
  2588. {
  2589. if (strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)),".") &&
  2590. strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)),".."))
  2591. {
  2592. std::string fullPath = binDir;
  2593. fullPath += "/";
  2594. fullPath += dir.GetFile(static_cast<unsigned long>(fileNum));
  2595. if(cmSystemTools::FileIsDirectory(fullPath.c_str()))
  2596. {
  2597. cmCTestRemoveDirectory(fullPath.c_str());
  2598. }
  2599. else
  2600. {
  2601. if(!cmSystemTools::RemoveFile(fullPath.c_str()))
  2602. {
  2603. std::string m = "Remove failed on file: ";
  2604. m += fullPath;
  2605. cmSystemTools::ReportLastSystemError(m.c_str());
  2606. }
  2607. }
  2608. }
  2609. }
  2610. }
  2611. int cmCTest::RunConfigurationScript()
  2612. {
  2613. m_ConfigurationScript =
  2614. cmSystemTools::CollapseFullPath(m_ConfigurationScript.c_str());
  2615. // make sure the file exists
  2616. if (!cmSystemTools::FileExists(m_ConfigurationScript.c_str()))
  2617. {
  2618. return -1;
  2619. }
  2620. // create a cmake instance to read the configuration script
  2621. cmake cm;
  2622. cmGlobalGenerator gg;
  2623. gg.SetCMakeInstance(&cm);
  2624. // read in the list file to fill the cache
  2625. cmLocalGenerator *lg = gg.CreateLocalGenerator();
  2626. lg->SetGlobalGenerator(&gg);
  2627. // set a variable with the path to the current script
  2628. lg->GetMakefile()->AddDefinition("CTEST_SCRIPT_DIRECTORY",
  2629. cmSystemTools::GetFilenamePath(
  2630. m_ConfigurationScript).c_str());
  2631. lg->GetMakefile()->AddDefinition("CTEST_SCRIPT_NAME",
  2632. cmSystemTools::GetFilenameName(
  2633. m_ConfigurationScript).c_str());
  2634. if (!lg->GetMakefile()->ReadListFile(0, m_ConfigurationScript.c_str()))
  2635. {
  2636. return -2;
  2637. }
  2638. // no popup widows
  2639. cmSystemTools::SetRunCommandHideConsole(true);
  2640. // get some info that should be set
  2641. cmMakefile *mf = lg->GetMakefile();
  2642. const char *srcDir = mf->GetDefinition("CTEST_SOURCE_DIRECTORY");
  2643. const char *binDir = mf->GetDefinition("CTEST_BINARY_DIRECTORY");
  2644. const char *ctestCmd = mf->GetDefinition("CTEST_COMMAND");
  2645. const char *ctestEnv = mf->GetDefinition("CTEST_ENVIRONMENT");
  2646. // make sure the required info is here
  2647. if (!srcDir || !binDir || !ctestCmd)
  2648. {
  2649. cmSystemTools::Error("Some required settings in the configuration file were missing");
  2650. return -3;
  2651. }
  2652. // set any environment variables
  2653. if (ctestEnv)
  2654. {
  2655. static char ctestEnvStatic[100][5000];
  2656. std::vector<std::string> envArgs;
  2657. cmSystemTools::ExpandListArgument(ctestEnv,envArgs);
  2658. int numArgs = envArgs.size();
  2659. // we have a hard limit of 100 env args due to stupid format of putenv
  2660. if (numArgs > 100)
  2661. {
  2662. numArgs = 100;
  2663. }
  2664. // for each variable/argument do a putenv
  2665. int i;
  2666. for (i = 0; i < numArgs; ++i)
  2667. {
  2668. // also limit args to be at most 4K long
  2669. std::string::size_type size = envArgs[i].size();
  2670. if(size > 4999)
  2671. {
  2672. size = 4999;
  2673. }
  2674. strncpy(ctestEnvStatic[i], envArgs[i].c_str(), size);
  2675. ctestEnvStatic[i][4999] = 0;
  2676. putenv(ctestEnvStatic[i]);
  2677. }
  2678. }
  2679. // clear the binary directory?
  2680. if (mf->IsOn("CTEST_START_WITH_EMPTY_BINARY_DIRECTORY"))
  2681. {
  2682. // try to avoid deleting directories that we shouldn't
  2683. std::string check = binDir;
  2684. check += "/CMakeCache.txt";
  2685. if (cmSystemTools::FileExists(check.c_str()))
  2686. {
  2687. cmCTestRemoveDirectory(binDir);
  2688. }
  2689. }
  2690. // make sure the binary directory exists
  2691. if (!cmSystemTools::FileExists(binDir))
  2692. {
  2693. if (!cmSystemTools::MakeDirectory(binDir))
  2694. {
  2695. cmSystemTools::Error("Unable to create the binary directory");
  2696. return -4;
  2697. }
  2698. }
  2699. std::string command;
  2700. std::string output;
  2701. int retVal = 0;
  2702. bool res = 0;
  2703. // do an initial cvs update on the src dir
  2704. const char *cvsCmd = mf->GetDefinition("CTEST_CVS_COMMAND");
  2705. if (cvsCmd)
  2706. {
  2707. command = cvsCmd;
  2708. char updateVar[40];
  2709. int i;
  2710. for (i = 1; i < 10; ++i)
  2711. {
  2712. sprintf(updateVar,"CTEST_EXTRA_UPDATES_%i",i);
  2713. const char *updateVal = mf->GetDefinition(updateVar);
  2714. if (updateVal)
  2715. {
  2716. std::vector<std::string> cvsArgs;
  2717. cmSystemTools::ExpandListArgument(updateVal,cvsArgs);
  2718. if (cvsArgs.size() == 2)
  2719. {
  2720. std::string fullCommand = command;
  2721. fullCommand += " update ";
  2722. fullCommand += cvsArgs[1];
  2723. output.empty();
  2724. retVal = 0;
  2725. res = cmSystemTools::RunSingleCommand(fullCommand.c_str(), &output,
  2726. &retVal, cvsArgs[0].c_str(),
  2727. m_Verbose, 0 /*m_TimeOut*/);
  2728. if (!res || retVal != 0)
  2729. {
  2730. cmSystemTools::Error("Unable to perform extra cvs updates");
  2731. return -5;
  2732. }
  2733. }
  2734. }
  2735. }
  2736. }
  2737. // put the initial cache into the bin dir
  2738. if (mf->GetDefinition("CTEST_INITIAL_CACHE"))
  2739. {
  2740. const char *initCache = mf->GetDefinition("CTEST_INITIAL_CACHE");
  2741. std::string cacheFile = binDir;
  2742. cacheFile += "/CMakeCache.txt";
  2743. std::ofstream fout(cacheFile.c_str());
  2744. if(!fout)
  2745. {
  2746. return -6;
  2747. }
  2748. fout.write(initCache, strlen(initCache));
  2749. // Make sure the operating system has finished writing the file
  2750. // before closing it. This will ensure the file is finished before
  2751. // the check below.
  2752. fout.flush();
  2753. fout.close();
  2754. }
  2755. // do an initial cmake to setup the DartConfig file
  2756. const char *cmakeCmd = mf->GetDefinition("CTEST_CMAKE_COMMAND");
  2757. if (cmakeCmd)
  2758. {
  2759. command = cmakeCmd;
  2760. command += " \"";
  2761. command += srcDir;
  2762. output.empty();
  2763. command += "\"";
  2764. retVal = 0;
  2765. res = cmSystemTools::RunSingleCommand(command.c_str(), &output,
  2766. &retVal, binDir,
  2767. m_Verbose, 0 /*m_TimeOut*/);
  2768. if (!res || retVal != 0)
  2769. {
  2770. cmSystemTools::Error("Unable to run cmake");
  2771. return -7;
  2772. }
  2773. }
  2774. // run ctest
  2775. command = ctestCmd;
  2776. output.empty();
  2777. retVal = 0;
  2778. res = cmSystemTools::RunSingleCommand(command.c_str(), &output,
  2779. &retVal, binDir,
  2780. m_Verbose, 0 /*m_TimeOut*/);
  2781. // the main ctest return values need to be fixed
  2782. if (!res /* || retVal != 0 */)
  2783. {
  2784. cmSystemTools::Error("Unable to run ctest");
  2785. return -8;
  2786. }
  2787. return 0;
  2788. }
  2789. void cmCTest::StartXML(std::ostream& ostr)
  2790. {
  2791. ostr << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
  2792. << "<Site BuildName=\"" << m_DartConfiguration["BuildName"]
  2793. << "\" BuildStamp=\"" << m_CurrentTag << "-"
  2794. << this->GetTestModelString() << "\" Name=\""
  2795. << m_DartConfiguration["Site"] << "\">" << std::endl;
  2796. }
  2797. void cmCTest::EndXML(std::ostream& ostr)
  2798. {
  2799. ostr << "</Site>" << std::endl;
  2800. }
  2801. bool cmCTest::ProcessMemCheckPurifyOutput(const std::string&, std::string& log,
  2802. int* results)
  2803. {
  2804. if ( !cmSystemTools::FileExists(m_MemoryTesterOutputFile.c_str()) )
  2805. {
  2806. log = "Cannot find Purify output file: " + m_MemoryTesterOutputFile;
  2807. std::cerr << log.c_str() << std::endl;
  2808. return false;
  2809. }
  2810. std::ifstream ifs(m_MemoryTesterOutputFile.c_str());
  2811. if ( !ifs )
  2812. {
  2813. log = "Cannot read Purify output file: " + m_MemoryTesterOutputFile;
  2814. std::cerr << log.c_str() << std::endl;
  2815. return false;
  2816. }
  2817. cmOStringStream ostr;
  2818. log = "";
  2819. cmsys::RegularExpression pfW("^\\[[WEI]\\] ([A-Z][A-Z][A-Z][A-Z]*): ");
  2820. std::string line;
  2821. while ( cmSystemTools::GetLineFromStream(ifs, line) )
  2822. {
  2823. int failure = cmCTest::NO_MEMORY_FAULT;
  2824. if ( pfW.find(line) )
  2825. {
  2826. int cc;
  2827. for ( cc = 0; cc < cmCTest::NO_MEMORY_FAULT; cc ++ )
  2828. {
  2829. if ( pfW.match(1) == cmCTestMemCheckResultStrings[cc] )
  2830. {
  2831. failure = cc;
  2832. break;
  2833. }
  2834. }
  2835. if ( cc == cmCTest::NO_MEMORY_FAULT )
  2836. {
  2837. std::cerr<< "Unknown Purify memory fault: " << pfW.match(1) << std::endl;
  2838. ostr << "*** Unknown Purify memory fault: " << pfW.match(1) << std::endl;
  2839. }
  2840. }
  2841. if ( failure != NO_MEMORY_FAULT )
  2842. {
  2843. ostr << "<b>" << cmCTestMemCheckResultStrings[failure] << "</b> ";
  2844. results[failure] ++;
  2845. }
  2846. ostr << cmCTest::MakeXMLSafe(line) << std::endl;
  2847. }
  2848. log = ostr.str();
  2849. return true;
  2850. }
  2851. bool cmCTest::ProcessMemCheckValgrindOutput(const std::string& str, std::string& log,
  2852. int* results)
  2853. {
  2854. std::vector<cmStdString> lines;
  2855. cmSystemTools::Split(str.c_str(), lines);
  2856. std::string::size_type cc;
  2857. cmOStringStream ostr;
  2858. log = "";
  2859. cmsys::RegularExpression valgrindLine("^==[0-9][0-9]*==");
  2860. cmsys::RegularExpression vgFIM(
  2861. "== .*Invalid free\\(\\) / delete / delete\\[\\]");
  2862. cmsys::RegularExpression vgFMM(
  2863. "== .*Mismatched free\\(\\) / delete / delete \\[\\]");
  2864. cmsys::RegularExpression vgMLK(
  2865. "== .*[0-9][0-9]* bytes in [0-9][0-9]* blocks are definitely lost"
  2866. " in loss record [0-9][0-9]* of [0-9]");
  2867. cmsys::RegularExpression vgPAR(
  2868. "== .*Syscall param .* contains unaddressable byte\\(s\\)");
  2869. cmsys::RegularExpression vgMPK1(
  2870. "== .*[0-9][0-9]* bytes in [0-9][0-9]* blocks are possibly lost in"
  2871. " loss record [0-9][0-9]* of [0-9]");
  2872. cmsys::RegularExpression vgMPK2(
  2873. "== .*[0-9][0-9]* bytes in [0-9][0-9]* blocks are still reachable"
  2874. " in loss record [0-9][0-9]* of [0-9]");
  2875. cmsys::RegularExpression vgUMC(
  2876. "== .*Conditional jump or move depends on uninitialised value\\(s\\)");
  2877. cmsys::RegularExpression vgUMR1("== .*Use of uninitialised value of size [0-9][0-9]*");
  2878. cmsys::RegularExpression vgUMR2("== .*Invalid read of size [0-9][0-9]*");
  2879. cmsys::RegularExpression vgUMR3("== .*Jump to the invalid address ");
  2880. cmsys::RegularExpression vgUMR4(
  2881. "== .*Syscall param .* contains uninitialised or unaddressable byte\\(s\\)");
  2882. cmsys::RegularExpression vgIPW("== .*Invalid write of size [0-9]");
  2883. for ( cc = 0; cc < lines.size(); cc ++ )
  2884. {
  2885. if ( valgrindLine.find(lines[cc]) )
  2886. {
  2887. int failure = cmCTest::NO_MEMORY_FAULT;
  2888. if ( vgFIM.find(lines[cc]) ) { failure = cmCTest::FIM; }
  2889. else if ( vgFMM.find(lines[cc]) ) { failure = cmCTest::FMM; }
  2890. else if ( vgMLK.find(lines[cc]) ) { failure = cmCTest::MLK; }
  2891. else if ( vgPAR.find(lines[cc]) ) { failure = cmCTest::PAR; }
  2892. else if ( vgMPK1.find(lines[cc]) ){ failure = cmCTest::MPK; }
  2893. else if ( vgMPK2.find(lines[cc]) ){ failure = cmCTest::MPK; }
  2894. else if ( vgUMC.find(lines[cc]) ) { failure = cmCTest::UMC; }
  2895. else if ( vgUMR1.find(lines[cc]) ){ failure = cmCTest::UMR; }
  2896. else if ( vgUMR2.find(lines[cc]) ){ failure = cmCTest::UMR; }
  2897. else if ( vgUMR3.find(lines[cc]) ){ failure = cmCTest::UMR; }
  2898. else if ( vgUMR4.find(lines[cc]) ){ failure = cmCTest::UMR; }
  2899. else if ( vgIPW.find(lines[cc]) ) { failure = cmCTest::IPW; }
  2900. if ( failure != cmCTest::NO_MEMORY_FAULT )
  2901. {
  2902. ostr << "<b>" << cmCTestMemCheckResultStrings[failure] << "</b> ";
  2903. results[failure] ++;
  2904. }
  2905. ostr << cmCTest::MakeXMLSafe(lines[cc]) << std::endl;
  2906. }
  2907. }
  2908. log = ostr.str();
  2909. return true;
  2910. }
  2911. bool cmCTest::ProcessMemCheckOutput(const std::string& str, std::string& log, int* results)
  2912. {
  2913. std::string::size_type cc;
  2914. for ( cc = 0; cc < cmCTest::NO_MEMORY_FAULT; cc ++ )
  2915. {
  2916. results[cc] = 0;
  2917. }
  2918. if ( m_MemoryTesterStyle == cmCTest::VALGRIND )
  2919. {
  2920. return ProcessMemCheckValgrindOutput(str, log, results);
  2921. }
  2922. else if ( m_MemoryTesterStyle == cmCTest::PURIFY )
  2923. {
  2924. return ProcessMemCheckPurifyOutput(str, log, results);
  2925. }
  2926. else if ( m_MemoryTesterStyle == cmCTest::BOUNDS_CHECKER )
  2927. {
  2928. log.append("\nMemory checking style used was: ");
  2929. log.append("Bounds Checker");
  2930. }
  2931. else
  2932. {
  2933. log.append("\nMemory checking style used was: ");
  2934. log.append("None that I know");
  2935. log = str;
  2936. }
  2937. return true;
  2938. }