utests.pp 38 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397
  1. {$mode objfpc}
  2. {$h+}
  3. unit utests;
  4. interface
  5. uses cgiapp,sysutils,mysql50conn,sqldb,whtml,dbwhtml,db,
  6. tresults,
  7. Classes,ftFont,fpimage,fpimgcanv,fpWritePng,fpcanvas;
  8. const
  9. TestsuiteURLPrefix='http://www.freepascal.org/testsuite/';
  10. TestsuiteCGIURL = TestsuiteURLPrefix+'cgi-bin/testsuite.cgi';
  11. ViewVCURL='http://svn.freepascal.org/cgi-bin/viewvc.cgi/trunk/tests/';
  12. Type
  13. TTestSuite = Class(TCgiApplication)
  14. Private
  15. FHTMLWriter : THtmlWriter;
  16. FComboBoxProducer : TComboBoxProducer;
  17. FDB : TSQLConnection;
  18. FTrans : TSQLTransaction;
  19. FRunID,
  20. FCompareRunID,
  21. FTestFileID,
  22. FTestFileName,
  23. FVersion,
  24. FCPU,
  25. FOS : String;
  26. FDate : TDateTime;
  27. FDebug,
  28. FNoSkipped,
  29. FOnlyFailed : Boolean;
  30. FRunSkipCount,
  31. FRunFailedCount,
  32. FRunCount : Integer;
  33. FAction,
  34. FLimit : Integer;
  35. FTestLastDays : Integer;
  36. FNeedEnd : boolean;
  37. Procedure GetOverviewRowAttr(Sender : TObject; Var BGColor : String;
  38. Var Align : THTMLAlign; Var VAlign : THTMLValign;
  39. Var CustomAttr : String) ;
  40. Procedure GetRunRowAttr(Sender : TObject; Var BGColor : String;
  41. Var Align : THTMLAlign; Var VAlign : THTMLValign;
  42. Var CustomAttr : String) ;
  43. Procedure FormatFailedOverview(Sender : TObject; Var CellData : String);
  44. Procedure FormatTestRunOverview(Sender : TObject; Var CellData : String);
  45. Procedure FormatFileDetails(Sender: TObject; var CellData: String);
  46. Procedure FormatTestResult(Sender: TObject; var CellData: String);
  47. Procedure DoDrawPie(Img : TFPCustomImage; Skipped,Failed,Total : Integer);
  48. Public
  49. Function CreateDataset(Qry : String) : TSQLQuery;
  50. Function CreateTableProducer(DS : TDataset) :TTableProducer;
  51. Procedure DefaultTableFromQuery(Qry,ALink : String; IncludeRecordCount : Boolean);
  52. Procedure ComboBoxFromQuery(Const ComboName,Qry : String);
  53. Procedure ComboBoxFromQuery(Const ComboName,Qry,Value : String);
  54. Function GetSingleTon(Const Qry : String) : String;
  55. Function GetOSName(ID : String) : String;
  56. Function GetCPUName(ID : String) : String;
  57. Function GetVersionName(ID : String) : String;
  58. Function GetTestFileName(ID : String) : String;
  59. Function InitCGIVars : Integer;
  60. Procedure DoRun; override;
  61. Procedure EmitOverviewForm;
  62. Procedure ShowRunResults;
  63. Procedure ShowRunComparison;
  64. Procedure ShowOneTest;
  65. Function ConnectToDB : Boolean;
  66. procedure DisconnectFromDB;
  67. Procedure EmitTitle(ATitle : String);
  68. Procedure EmitEnd;
  69. Procedure ShowRunOverview;
  70. Procedure CreateRunPie;
  71. Function ShowRunData : Boolean;
  72. end;
  73. implementation
  74. Const
  75. {$i utests.cfg}
  76. { if utests.cfg is missed, create one with the following contents:
  77. DefDatabase = 'TESTSUITE';
  78. DefHost = '';
  79. DefDBUser = ''; // fill this in when compiling.
  80. DefPassword = ''; // fill this in, too.
  81. }
  82. Const
  83. SDetailsURL = TestsuiteCGIURL + '?action=1&run1id=%s';
  84. Procedure TTestSuite.DoRun;
  85. begin
  86. Try
  87. Try
  88. Case InitCGIVars of
  89. 0 : EmitOverviewForm;
  90. 1 :
  91. if Length(FCompareRunID) = 0 then
  92. ShowRunResults
  93. else
  94. ShowRunComparison;
  95. 2 : CreateRunPie;
  96. 3 : ShowOneTest;
  97. {$ifdef TEST}
  98. 98 :
  99. begin
  100. EmitOverviewForm;
  101. Writeln(stdout,'<PRE>');
  102. FreeMem(pointer($ffffffff));
  103. Writeln(stdout,'</PRE>');
  104. end;
  105. 99 :
  106. begin
  107. EmitOverviewForm;
  108. Writeln(stdout,'<PRE>');
  109. Dump_stack(stdout,get_frame);
  110. Writeln(stdout,'</PRE>');
  111. end;
  112. {$endif TEST}
  113. end;
  114. finally
  115. EmitEnd;
  116. DisConnectFromDB;
  117. end;
  118. Finally
  119. Terminate;
  120. end;
  121. end;
  122. Function TTestSuite.InitCGIVars : Integer;
  123. Var
  124. S : String;
  125. begin
  126. FHtmlWriter:=THTMLWriter.Create(Response);
  127. FComboBoxProducer:=TComboBoxProducer.Create(Self);
  128. DateSeparator:='/';
  129. Result:=0;
  130. S:=RequestVariables['action'];
  131. if Length(S) = 0 then
  132. S:=RequestVariables['TESTACTION'];
  133. FAction:=StrToIntDef(S,0);
  134. S:=RequestVariables['limit'];
  135. if Length(S) = 0 then
  136. S:=RequestVariables['TESTLIMIT'];
  137. FLimit:=StrToIntDef(S,50);
  138. FVersion:=RequestVariables['version'];
  139. if Length(FVersion) = 0 then
  140. FVersion:=RequestVariables['TESTVERSION'];
  141. FOS:=RequestVariables['os'];
  142. if Length(FOS) = 0 then
  143. FOS:=RequestVariables['TESTOS'];
  144. FCPU:=RequestVariables['cpu'];
  145. if Length(FCPU) = 0 then
  146. FCPU:=RequestVariables['TESTCPU'];
  147. FRunID:=RequestVariables['run1id'];
  148. if Length(FRunID) = 0 then
  149. FRunID:=RequestVariables['TESTRUN'];
  150. S:=RequestVariables['lastdays'];
  151. if Length(S) = 0 then
  152. S:=RequestVariables['TESTLASTDAYS'];
  153. FTestLastDays:=StrToIntDef(S,31);
  154. S:=RequestVariables['date'];
  155. if Length(S) = 0 then
  156. S:=RequestVariables['TESTDATE'];
  157. if Length(S) > 0 then
  158. try
  159. FDate:=StrToDate(S);
  160. except
  161. FDate:=0;
  162. end;
  163. S:=RequestVariables['failedonly'];
  164. if Length(S) = 0 then
  165. S:=RequestVariables['TESTFAILEDONLY'];
  166. FOnlyFailed:=(S='1');
  167. S:=RequestVariables['noskipped'];
  168. if Length(S) = 0 then
  169. S:=RequestVariables['TESTNOSKIPPED'];
  170. FNoSkipped:=(S='1');
  171. FCompareRunID:=RequestVariables['run2id'];
  172. FTestFileID:=RequestVariables['testfileid'];
  173. FTestFileName:=RequestVariables['testfilename'];
  174. FRunCount:=StrToIntDef(RequestVariables['PIETOTAL'],0);
  175. FRunSkipCount:=StrToIntDef(RequestVariables['PIESKIPPED'],0);
  176. FRunFailedCount:=StrToIntDef(RequestVariables['PIEFAILED'],0);
  177. S:=RequestVariables['DEBUGCGI'];
  178. FDebug:=(S='1');
  179. Result:=FAction;
  180. end;
  181. Function TTestSuite.ConnectToDB : Boolean;
  182. begin
  183. Result:=False;
  184. FDB:=TMySQl50Connection.Create(Self);
  185. FDB.HostName:=DefHost;
  186. FDB.DatabaseName:=DefDatabase;
  187. FDB.UserName:=DefDBUser;
  188. FDB.Password:=DefPassword;
  189. FTrans := TSQLTransaction.Create(nil);
  190. FTrans.DataBase := FDB;
  191. FDB.Transaction := FTrans;
  192. FDB.Connected:=True;
  193. Result:=True;
  194. end;
  195. procedure TTestSuite.DisconnectFromDB;
  196. begin
  197. If Assigned(FDB) then
  198. begin
  199. if (FDB.Connected) then
  200. FDB.Connected:=False;
  201. FreeAndNil(FDB);
  202. FreeAndNil(FTrans);
  203. end;
  204. end;
  205. Procedure TTestSuite.ComboBoxFromQuery(Const ComboName,Qry: String);
  206. begin
  207. ComboBoxFromQuery(ComboName,Qry,'')
  208. end;
  209. Procedure TTestSuite.ComboBoxFromQuery(Const ComboName,Qry,Value : String);
  210. Var
  211. Q : TSQLQuery;
  212. begin
  213. Q:=TSQLQuery.Create(Self);
  214. try
  215. Q.Database:=FDB;
  216. Q.Transaction:=FTrans;
  217. Q.SQL.Text:=Qry;
  218. Q.Open;
  219. FComboboxProducer.Dataset:=Q;
  220. FComboBoxProducer.ValueField:=Q.Fields[0].FieldName;
  221. FComboBoxProducer.DataField:=Q.Fields[1].FieldName;
  222. FComboBoxProducer.Value:=Value;
  223. FComboBoxProducer.InputName:=ComboName;
  224. FComboBoxProducer.CreateComboBox(Response);
  225. Finally
  226. Q.Free;
  227. end;
  228. end;
  229. Function TTestSuite.GetSingleton(Const Qry : String) : String;
  230. Var
  231. Q : TSQLQuery;
  232. begin
  233. Result:='';
  234. if FDEbug then
  235. begin
  236. system.Writeln('Query=',Qry);
  237. system.flush(output);
  238. end;
  239. Q:=TSQLQuery.Create(Self);
  240. try
  241. Q.Database:=FDB;
  242. Q.Transaction:=FTrans;
  243. Q.SQL.Text:=Qry;
  244. Q.Open;
  245. Try
  246. if FDebug and (Q.FieldCount<>1) then
  247. begin
  248. system.Writeln('GetSingleton number of fields is not 1, but ',
  249. Q.FieldCount);
  250. system.flush(output);
  251. end;
  252. If Not (Q.EOF and Q.BOF) then
  253. Result:=Q.Fields[0].AsString;
  254. Finally
  255. Q.Close;
  256. end;
  257. finally
  258. Q.Free;
  259. end;
  260. end;
  261. Procedure TTestSuite.EmitTitle(ATitle : String);
  262. begin
  263. AddResponseLn('<HTML>');
  264. AddResponseLn('<TITLE>'+ATitle+'</TITLE>');
  265. AddResponseLn('<BODY>');
  266. FNeedEnd:=true;
  267. end;
  268. Procedure TTestSuite.EmitOverviewForm;
  269. begin
  270. ConnectToDB;
  271. ContentType:='text/html';
  272. EmitContentType;
  273. EmitTitle(Title);
  274. With FHTMLWriter do
  275. begin
  276. HeaderStart(1);
  277. Write('View Test suite results');
  278. HeaderEnd(1);
  279. Write('Please specify search criteria:');
  280. ParagraphStart;
  281. FormStart(TestsuiteCGIURL,'');
  282. TableStart(2,true);
  283. RowStart;
  284. CellStart;
  285. Write('Operating system:');
  286. CellNext;
  287. ComboBoxFromQuery('os','SELECT TO_ID,TO_NAME FROM TESTOS ORDER BY TO_NAME',FOS);
  288. CellEnd;
  289. RowNext;
  290. CellStart;
  291. Write('Processor:');
  292. CellNext;
  293. ComboBoxFromQuery('cpu','SELECT TC_ID,TC_NAME FROM TESTCPU ORDER BY TC_NAME',FCPU);
  294. CellEnd;
  295. RowNext;
  296. CellStart;
  297. Write('Version');
  298. CellNext;
  299. ComboBoxFromQuery('version','SELECT TV_ID,TV_VERSION FROM TESTVERSION ORDER BY TV_VERSION DESC',FVERSION);
  300. CellEnd;
  301. RowNext;
  302. CellStart;
  303. Write('Date');
  304. CellNext;
  305. If (FDate=0) then
  306. EmitInput('date','')
  307. else
  308. EmitInput('date',DateToStr(FDate));
  309. CellEnd;
  310. RowNext;
  311. CellStart;
  312. Write('Only failed tests');
  313. CellNext;
  314. EmitCheckBox('failedonly','1',FonlyFailed);
  315. CellEnd;
  316. RowNext;
  317. CellStart;
  318. Write('Hide skipped tests');
  319. CellNext;
  320. EmitCheckBox('noskipped','1',FNoSkipped);
  321. CellEnd;
  322. RowEnd;
  323. TableEnd;
  324. ParaGraphStart;
  325. EmitSubmitButton('','Search');
  326. EmitResetButton('','Reset form');
  327. FormEnd;
  328. end;
  329. ShowRunOverview;
  330. end;
  331. procedure TTestSuite.EmitEnd;
  332. begin
  333. if not FNeedEnd then
  334. exit;
  335. AddResponseLn('</BODY>');
  336. AddResponseLn('</HTML>');
  337. end;
  338. procedure TTestSuite.GetOverviewRowAttr(Sender: TObject; var BGColor: String;
  339. var Align: THTMLAlign; var VAlign: THTMLValign; var CustomAttr: String);
  340. begin
  341. If ((Sender as TTAbleProducer).CurrentRow mod 2=0) then
  342. BGColor:='#EEEEEE'
  343. end;
  344. Function TTestSuite.CreateDataset(Qry : String) : TSQLQuery;
  345. begin
  346. Result:=TSQLQuery.Create(Self);
  347. With Result do
  348. begin
  349. Database:=FDB;
  350. Transaction := FTrans;
  351. SQL.Text:=Qry;
  352. end;
  353. end;
  354. Function TTestSuite.CreateTableProducer(DS : TDataset) :TTableProducer;
  355. begin
  356. Result:=TTableProducer.Create(Self);
  357. Result.Dataset:=DS;
  358. end;
  359. Procedure TTestSuite.DefaultTableFromQuery(Qry,Alink : String; IncludeRecordCount : Boolean);
  360. Var
  361. Q : TSQLQuery;
  362. begin
  363. If FDebug then
  364. Writeln('Query : '+Qry);
  365. Q:=CreateDataset(Qry);
  366. With Q do
  367. try
  368. Open;
  369. Try
  370. With CreateTableProducer(Q) do
  371. Try
  372. Border:=True;
  373. If (Alink<>'') then
  374. begin
  375. CreateColumns(Nil);
  376. If TableColumns.Count>0 then
  377. (TableColumns.Items[0] as TTableColumn).ActionURL:=ALink;
  378. end;
  379. CreateTable(Response);
  380. Finally
  381. Free;
  382. end;
  383. If IncludeRecordCount then
  384. FHTMLWriter.DumpLn(Format('<p>Record count: %d </p>',[Q.RecordCount]));
  385. Finally
  386. Close;
  387. end;
  388. finally
  389. Free;
  390. end;
  391. end;
  392. Procedure TTestSuite.ShowRunOverview;
  393. Const
  394. SOverview = 'SELECT TU_ID as ID,TU_DATE as Date,TC_NAME as CPU,TO_NAME as OS,'+
  395. 'TV_VERSION as Version,COUNT(TR_ID) as Count,'+
  396. '(TU_SUCCESSFULLYFAILED+TU_SUCCESFULLYCOMPILED+TU_SUCCESSFULLYRUN) AS OK,'+
  397. '(TU_FAILEDTOCOMPILE+TU_FAILEDTORUN+TU_FAILEDTOFAIL) as Failed,'+
  398. '(TU_SUCCESSFULLYFAILED+TU_SUCCESFULLYCOMPILED+TU_SUCCESSFULLYRUN+'+
  399. 'TU_FAILEDTOCOMPILE+TU_FAILEDTORUN+TU_FAILEDTOFAIL) as Total,'+
  400. 'TU_SUBMITTER as Submitter, TU_MACHINE as Machine, TU_COMMENT as Comment '+
  401. 'FROM TESTRESULTS,TESTRUN,TESTCPU,TESTOS,TESTVERSION '+
  402. 'WHERE '+
  403. '(TC_ID=TU_CPU_FK) AND '+
  404. '(TO_ID=TU_OS_FK) AND '+
  405. '(TV_ID=TU_VERSION_FK) AND '+
  406. '(TR_TESTRUN_FK=TU_ID) '+
  407. '%s '+
  408. 'GROUP BY TU_ID '+
  409. 'ORDER BY TU_ID DESC LIMIT %d';
  410. Var
  411. S,A,Qry : String;
  412. Q : TSQLQuery;
  413. begin
  414. S:='';
  415. If (FCPU<>'') and (GetCPUName(FCPU)<>'All') then
  416. S:=S+' AND (TU_CPU_FK='+FCPU+')';
  417. If (FVersion<>'') and (GetVersionName(FVersion)<>'All') then
  418. S:=S+' AND (TU_VERSION_FK='+FVERSION+')';
  419. if (FOS<>'') and (GetOSName(FOS)<>'All') then
  420. S:=S+' AND (TU_OS_FK='+FOS+')';
  421. If (Round(FDate)<>0) then
  422. S:=S+' AND (TU_DATE="'+FormatDateTime('YYYY/MM/DD',FDate)+'")';
  423. If FOnlyFailed then
  424. S:=S+' AND (TR_OK="-")';
  425. A:=SDetailsURL;
  426. If FOnlyFailed then
  427. A:=A+'&failedonly=1';
  428. If FNoSkipped then
  429. A:=A+'&noskipped=1';
  430. Qry:=Format(SOverview,[S,FLimit]);
  431. If FDebug then
  432. Writeln('Query : '+Qry);
  433. Q:=CreateDataset(Qry);
  434. With Q do
  435. try
  436. Open;
  437. Try
  438. With CreateTableProducer(Q) do
  439. Try
  440. Border:=True;
  441. OnGetRowAttributes:=@GetOverViewRowAttr;
  442. CreateColumns(Nil);
  443. TableColumns.ColumnByName('ID').ActionURL:=A;
  444. TableColumns.ColumnByNAme('Failed').OnGetCellContents:=@FormatFailedOverview;
  445. CreateTable(Response);
  446. Finally
  447. Free;
  448. end;
  449. FHTMLWriter.DumpLn(Format('<p>Record count: %d</p>',[Q.RecordCount]));
  450. Finally
  451. Close;
  452. end;
  453. finally
  454. Free;
  455. end;
  456. end;
  457. Function TTestSuite.GetOSName(ID : String) : String;
  458. begin
  459. if (ID<>'') then
  460. Result:=GetSingleTon('SELECT TO_NAME FROM TESTOS WHERE TO_ID='+ID);
  461. end;
  462. Function TTestSuite.GetTestFileName(ID : String) : String;
  463. begin
  464. if (ID<>'') then
  465. Result:=GetSingleTon('SELECT T_NAME FROM TESTS WHERE T_ID='+ID);
  466. end;
  467. Function TTestSuite.GetCPUName(ID : String) : String;
  468. begin
  469. if (ID<>'') then
  470. Result:=GetSingleTon('SELECT TC_NAME FROM TESTCPU WHERE TC_ID='+ID);
  471. end;
  472. Function TTestSuite.GetVersionName(ID : String) : String;
  473. begin
  474. if (ID<>'') then
  475. Result:=GetSingleton('SELECT TV_VERSION FROM TESTVERSION WHERE TV_ID='+ID);
  476. end;
  477. Function TTestSuite.ShowRunData : Boolean;
  478. Const
  479. SGetRunData = 'SELECT TU_ID,TU_DATE,TC_NAME,TO_NAME,' +
  480. 'TU_SUBMITTER,TU_MACHINE,TU_COMMENT,TV_VERSION '+
  481. ' FROM TESTRUN,TESTCPU,TESTOS,TESTVERSION '+
  482. 'WHERE '+
  483. ' (TC_ID=TU_CPU_FK) AND '+
  484. ' (TO_ID=TU_OS_FK) AND '+
  485. ' (TV_ID=TU_VERSION_FK) AND '+
  486. ' (TU_ID=%s)';
  487. Var
  488. Q1,Q2 : TSQLQuery;
  489. F : TField;
  490. Date1, Date2: TDateTime;
  491. begin
  492. Result:=(FRunID<>'');
  493. If Result then
  494. begin
  495. Q1:=CreateDataset(Format(SGetRunData,[FRunID]));
  496. if Length(FCompareRunID) > 0 then
  497. Q2:=CreateDataset(Format(SGetRunData,[FCompareRunID]))
  498. else
  499. Q2:=nil;
  500. Try
  501. Q1.Open;
  502. if Q2 <> nil then
  503. Q2.Open;
  504. Result:=Not (Q1.EOF and Q1.BOF);
  505. If Result then
  506. With FHTMLWriter do
  507. begin
  508. FormStart(TestsuiteCGIURL,'get');
  509. EmitHiddenVar('action', '1');
  510. TableStart(3,true);
  511. RowStart;
  512. CellStart;
  513. Write('Run ID:');
  514. CellNext;
  515. EmitInput('run1id',FRunID);
  516. CellNext;
  517. EmitInput('run2id',FCompareRunID);
  518. CellEnd;
  519. RowNext;
  520. CellStart;
  521. Write('Operating system:');
  522. CellNext;
  523. Write(Q1.FieldByName('TO_NAME').AsString);
  524. CellNext;
  525. if Q2 <> nil then
  526. Write(Q2.FieldByName('TO_NAME').AsString);
  527. CellEnd;
  528. RowNext;
  529. CellStart;
  530. Write('Processor:');
  531. CellNext;
  532. Write(Q1.FieldByName('TC_NAME').AsString);
  533. CellNext;
  534. if Q2 <> nil then
  535. Write(Q2.FieldByName('TC_NAME').AsString);
  536. CellEnd;
  537. RowNext;
  538. CellStart;
  539. Write('Version:');
  540. CellNext;
  541. Write(Q1.FieldByNAme('TV_VERSION').AsString);
  542. CellNext;
  543. if Q2 <> nil then
  544. Write(Q2.FieldByNAme('TV_VERSION').AsString);
  545. CellEnd;
  546. RowNext;
  547. CellStart;
  548. Write('Comment:');
  549. CellNext;
  550. Write(Q1.FieldByName('TU_COMMENT').AsString);
  551. CellNext;
  552. if Q2 <> nil then
  553. Write(Q2.FieldByName('TU_COMMENT').AsString);
  554. CellEnd;
  555. RowNext;
  556. CellStart;
  557. Write('Machine:');
  558. CellNext;
  559. Write(Q1.FieldByName('TU_MACHINE').AsString);
  560. CellNext;
  561. if Q2 <> nil then
  562. Write(Q2.FieldByName('TU_MACHINE').AsString);
  563. CellEnd;
  564. RowNext;
  565. CellStart;
  566. Write('Submitter:');
  567. CellNext;
  568. Write(Q1.FieldByName('TU_SUBMITTER').AsString);
  569. CellNext;
  570. if Q2 <> nil then
  571. Write(Q2.FieldByName('TU_SUBMITTER').AsString);
  572. CellEnd;
  573. RowNext;
  574. CellStart;
  575. Write('Date:');
  576. CellNext;
  577. F := Q1.FieldByName('TU_DATE');
  578. Date1 := F.AsDateTime;
  579. Write(F.AsString);
  580. CellNext;
  581. if Q2 <> nil then
  582. begin
  583. F := Q2.FieldByName('TU_DATE');
  584. Date2 := F.AsDateTime;
  585. Write(F.AsString);
  586. end;
  587. CellEnd;
  588. RowEnd;
  589. TableEnd;
  590. ParagraphStart;
  591. EmitCheckBox('noskipped','1',FNoSkipped);
  592. Write(' Hide skipped tests');
  593. ParagraphEnd;
  594. ParagraphStart;
  595. EmitCheckBox('failedonly','1',FonlyFailed);
  596. Write(' Hide successful tests');
  597. ParagraphEnd;
  598. ParaGraphStart;
  599. EmitSubmitButton('','Show/Compare');
  600. EmitResetButton('','Reset form');
  601. ParagraphEnd;
  602. FormEnd;
  603. { give warning if dates reversed }
  604. if (Q2 <> nil) and (Date1 > Date2) then
  605. begin
  606. ParagraphStart;
  607. Write('Warning: testruns are not compared in chronological order.');
  608. ParagraphEnd;
  609. end;
  610. end;
  611. Finally
  612. Q1.Close;
  613. Q1.Free;
  614. if Q2 <> nil then
  615. begin
  616. Q2.Close;
  617. Q2.Free;
  618. end;
  619. end;
  620. end;
  621. end;
  622. Procedure TTestSuite.ShowRunResults;
  623. Var
  624. S : String;
  625. Qry : String;
  626. Q : TSQLQuery;
  627. FL : String;
  628. begin
  629. ConnectToDB;
  630. ContentType:='text/html';
  631. EmitContentType;
  632. EmitTitle(Title+' : Search Results');
  633. With FHTMLWriter do
  634. begin
  635. HeaderStart(1);
  636. Write('Test suite results for run '+FRunID);
  637. HeaderEnd(1);
  638. HeaderStart(2);
  639. Write('Test run data : ');
  640. HeaderEnd(2);
  641. If ShowRunData then
  642. begin
  643. HeaderStart(2);
  644. Write('Detailed test run results:');
  645. FL:='';
  646. If FOnlyFailed or FNoSkipped then
  647. begin
  648. FL:='';
  649. If FOnlyFailed then
  650. FL:='successful';
  651. if FNoSkipped then
  652. begin
  653. If (FL<>'') then
  654. FL:=FL+' and ';
  655. FL:=FL+'skipped';
  656. end;
  657. Write(' ('+FL+' tests are hidden)');
  658. end;
  659. HeaderEnd(2);
  660. ParaGraphStart;
  661. S:='SELECT T_ID as Id,T_NAME as Filename,TR_SKIP as Skipped'
  662. +',TR_OK as OK,TR_RESULT as Result'
  663. +' FROM TESTRESULTS,TESTS'
  664. +' WHERE (TR_TEST_FK=T_ID) AND (TR_TESTRUN_FK='+FRunID+') ';
  665. If FOnlyFailed then
  666. S:=S+' AND (TR_OK="-")';
  667. If FNoSkipped then
  668. S:=S+' AND (TR_SKIP="-")';
  669. S:=S+' ORDER BY TR_ID ';
  670. Qry:=S;
  671. If FDebug then
  672. begin
  673. Writeln('Query : '+Qry);
  674. Flush(stdout);
  675. end;
  676. FRunCount:=0;
  677. FRunSkipCount:=0;
  678. FRunFailedCount:=0;
  679. Q:=CreateDataset(Qry);
  680. With Q do
  681. try
  682. Open;
  683. Try
  684. With CreateTableProducer(Q) do
  685. Try
  686. Border:=True;
  687. FL:='Id,Filename';
  688. If Not FNoSkipped then
  689. FL:=FL+',Skipped';
  690. If Not FOnlyFailed then
  691. FL:=FL+',OK';
  692. FL:=FL+',Result';
  693. CreateColumns(FL);
  694. OnGetRowAttributes:=@GetRunRowAttr;
  695. TableColumns.ColumnByNAme('Filename').OnGetCellContents:=
  696. @FormatFileDetails;
  697. TableColumns.ColumnByNAme('Result').OnGetCellContents:=
  698. @FormatTestResult;
  699. //(TableColumns.Items[0] as TTableColumn).ActionURL:=ALink;
  700. CreateTable(Response);
  701. Finally
  702. Free;
  703. end;
  704. DumpLn(Format('<p>Record count: %d </p>',[Q.RecordCount]));
  705. Finally
  706. Close;
  707. end;
  708. finally
  709. Free;
  710. end;
  711. If Not (FRunCount=0) and not (FNoSkipped or FOnlyFailed) then
  712. begin
  713. ParaGraphStart;
  714. TagStart('IMG',Format('Src="'+TestsuiteCGIURL+'?action=2&pietotal=%d&piefailed=%d&pieskipped=%d"',[FRunCount,FRunFailedCount,FRunSkipCount]));
  715. end;
  716. end
  717. else
  718. Write('No data for test run with ID: '+FRunID);
  719. end;
  720. end;
  721. Procedure TTestSuite.ShowOneTest;
  722. Var
  723. S : String;
  724. Qry : String;
  725. Q : TSQLQuery;
  726. i : longint;
  727. FieldName,FieldValue,
  728. Log,Source : String;
  729. Res : Boolean;
  730. begin
  731. ConnectToDB;
  732. ContentType:='text/html';
  733. EmitContentType;
  734. if FTestFileID='' then
  735. FTestFileID:=GetSingleton('SELECT T_ID FROM TESTS WHERE T_NAME LIKE ''%'+
  736. FTestFileName+'%''');
  737. if FTestFileID<>'' then
  738. FTestFileName:=GetTestFileName(FTestFileID);
  739. EmitTitle(Title+' : File '+FTestFileName+' Results');
  740. With FHTMLWriter do
  741. begin
  742. HeaderStart(1);
  743. Write('Test suite results for test file '+FTestFileName);
  744. HeaderEnd(1);
  745. HeaderStart(2);
  746. Write('Test run data : ');
  747. HeaderEnd(2);
  748. if FRunID<>'' then
  749. begin
  750. Res:=ShowRunData;
  751. Res:=true;
  752. end
  753. else
  754. begin
  755. // This is useless as it is now
  756. // It should be integrated into a form probably PM
  757. Write('Only failed tests');
  758. EmitCheckBox('failedonly','1',FonlyFailed);
  759. Write('Hide skipped tests');
  760. EmitCheckBox('noskipped','1',FNoSkipped);
  761. Res:=true;
  762. end;
  763. If Res then
  764. begin
  765. HeaderStart(2);
  766. Write('Test file "'+FTestFileName+'" information:');
  767. HeaderEnd(2);
  768. ParaGraphStart;
  769. if FTestFileID<>'' then
  770. S:='SELECT * FROM TESTS WHERE T_ID='+FTestFileID
  771. else
  772. S:='SELECT * FROM TESTS WHERE T_NAME='+FTestFileName;
  773. Q:=CreateDataSet(S);
  774. With Q do
  775. Try
  776. Open;
  777. Try
  778. For i:=0 to FieldCount-1 do
  779. begin
  780. FieldValue:=Fields[i].AsString;
  781. FieldName:=Fields[i].DisplayName;
  782. if (FieldValue<>'') and (FieldValue<>'-') and
  783. (FieldName<>'T_NAME') and (FieldName<>'T_SOURCE') then
  784. begin
  785. if (FieldValue='+') then
  786. Write('Flag ');
  787. Write(FieldName);
  788. Write(' ');
  789. if FieldValue='+' then
  790. Write(' set')
  791. else
  792. Write(FieldValue);
  793. DumpLn('<BR>');
  794. end;
  795. end;
  796. Finally
  797. Close;
  798. end;
  799. Finally
  800. Free;
  801. end;
  802. ParaGraphEnd;
  803. HeaderStart(2);
  804. Write('Detailed test run results:');
  805. HeaderEnd(2);
  806. ParaGraphStart;
  807. S:='SELECT TR_ID,TR_TESTRUN_FK,TR_TEST_FK,TR_OK, TR_SKIP,TR_RESULT '
  808. //S:='SELECT * '
  809. +' FROM TESTRESULTS '
  810. +' WHERE (TR_TEST_FK='+FTestFileID+')';
  811. If FOnlyFailed then
  812. S:=S+' AND (TR_OK="-")';
  813. if Fcomparerunid<>'' then
  814. S:=S+' AND ((TR_TESTRUN_FK='+Frunid+') OR '+
  815. '(TR_TESTRUN_FK='+Fcomparerunid+'))'
  816. else if Frunid<>'' then
  817. S:=S+' AND (TR_TESTRUN_FK='+Frunid+')'
  818. else
  819. S:=S+' ORDER BY TR_TESTRUN_FK DESC LIMIT '+IntToStr(FLimit);
  820. Qry:=S;
  821. If FDebug then
  822. begin
  823. Writeln('Query : '+Qry);
  824. Flush(stdout);
  825. end;
  826. FRunCount:=0;
  827. FRunSkipCount:=0;
  828. FRunFailedCount:=0;
  829. Q:=CreateDataset(Qry);
  830. With Q do
  831. try
  832. Open;
  833. Try
  834. With CreateTableProducer(Q) do
  835. Try
  836. Border:=True;
  837. //FL:='TR_ID,TR_TESTRUN_FK,T_NAME,T_CPU,T_VERSION';
  838. CreateColumns(Nil);
  839. TableColumns.ColumnByNAme('TR_TESTRUN_FK').OnGetCellContents:=
  840. @FormatTestRunOverview;
  841. //OnGetRowAttributes:=@GetRunRowAttr;
  842. TableColumns.ColumnByNAme('TR_RESULT').OnGetCellContents:=
  843. @FormatTestResult;
  844. //(TableColumns.Items[0] as TTableColumn).ActionURL:=ALink;
  845. CreateTable(Response);
  846. Finally
  847. Free;
  848. end;
  849. DumpLn(Format('<p>Record count: %d </p>',[Q.RecordCount]));
  850. Finally
  851. Close;
  852. end;
  853. finally
  854. Free;
  855. end;
  856. //If FDebug then
  857. if FRunId<>'' then
  858. begin
  859. log:='';
  860. Try
  861. log:=getsingleton('select TR_LOG from TESTRESULTS where (TR_TEST_FK='+ftestfileid
  862. +') and (TR_TESTRUN_FK='+frunid+')');
  863. if Log<>'' then
  864. begin
  865. HeaderStart(2);
  866. Write('Log of '+FRunId+':');
  867. HeaderEnd(2);
  868. PreformatStart;
  869. system.Write(Log);
  870. system.flush(output);
  871. PreformatEnd;
  872. end;
  873. Finally
  874. if Log='' then
  875. begin
  876. HeaderStart(2);
  877. Write('No log of '+FRunId+'.');
  878. HeaderEnd(2);
  879. end;
  880. end;
  881. end;
  882. if FCompareRunId<>'' then
  883. begin
  884. log:='';
  885. Try
  886. log:=getsingleton('select TR_LOG from TESTRESULTS where (TR_TEST_FK='+ftestfileid
  887. +') and (TR_TESTRUN_FK='+fcomparerunid+')');
  888. if Log<>'' then
  889. begin
  890. HeaderStart(2);
  891. Write('Log of '+FCompareRunId+':');
  892. HeaderEnd(2);
  893. PreformatStart;
  894. system.Write(Log);
  895. system.flush(output);
  896. PreformatEnd;
  897. end;
  898. Finally
  899. if Log='' then
  900. begin
  901. HeaderStart(2);
  902. Write('No log of '+FCompareRunId+'.');
  903. HeaderEnd(2);
  904. end;
  905. end;
  906. end;
  907. if FDebug then
  908. Write('After Log.');
  909. Source:='';
  910. Try
  911. Source:=getsingleton('select T_SOURCE from TESTS where T_ID='+ftestfileid);
  912. if Source<>'' then
  913. begin
  914. HeaderStart(2);
  915. Write('Source:');
  916. HeaderEnd(2);
  917. PreformatStart;
  918. system.Write(Source);
  919. system.flush(output);
  920. PreformatEnd;
  921. end;
  922. Finally
  923. if Source='' then
  924. begin
  925. HeaderStart(3);
  926. DumpLn('<P>No Source in TestSuite DataBase.</P>');
  927. DumpLn('Link to SVN view of '+
  928. '<A HREF="'+ViewVCURL+FTestFileName+'?view=markup'+
  929. '" TARGET="_blank"> '+FTestFileName+'</A> source. ');
  930. HeaderEnd(3);
  931. end
  932. else
  933. begin
  934. HeaderStart(3);
  935. DumpLn('Link to SVN view of '+
  936. '<A HREF="'+ViewVCURL+FTestFileName+'?view=markup'+
  937. '" TARGET="_blank"> '+FTestFileName+'</A> source. ');
  938. HeaderEnd(3);
  939. end;
  940. end;
  941. if FDebug then
  942. Write('After Source.');
  943. end
  944. else
  945. Write(Format('No data for test file with ID: %s',[FTestFileID]));
  946. end;
  947. end;
  948. Procedure TTestSuite.ShowRunComparison;
  949. Var
  950. S : String;
  951. Qry : String;
  952. Q : TSQLQuery;
  953. FL : String;
  954. begin
  955. ConnectToDB;
  956. ContentType:='text/html';
  957. EmitContentType;
  958. EmitTitle(Title+' : Compare 2 runs');
  959. With FHTMLWriter do
  960. begin
  961. HeaderStart(1);
  962. Write('Test suite results for run '+FRunID+' vs. '+FCompareRunID);
  963. HeaderEnd(1);
  964. HeaderStart(2);
  965. Write('Test run data: ');
  966. HeaderEnd(2);
  967. If ShowRunData then
  968. begin
  969. HeaderStart(2);
  970. Write('Detailed test run results:');
  971. FL:='';
  972. If FOnlyFailed or FNoSkipped then
  973. begin
  974. FL:='';
  975. If FOnlyFailed then
  976. FL:='successful';
  977. if FNoSkipped then
  978. begin
  979. If (FL<>'') then
  980. FL:=FL+' and ';
  981. FL:=FL+'skipped';
  982. end;
  983. Write(' ('+FL+' tests are hidden)');
  984. end;
  985. HeaderEnd(2);
  986. ParaGraphStart;
  987. Q:=CreateDataset('');
  988. Q.SQL.Text:='CREATE TEMPORARY TABLE tr1 like TESTRESULTS;';
  989. Q.ExecSQL;
  990. Q.SQL.Text:='CREATE TEMPORARY TABLE tr2 like TESTRESULTS;';
  991. Q.ExecSQL;
  992. Q.SQL.Text:='INSERT INTO tr1 SELECT * FROM TESTRESULTS '+
  993. 'WHERE TR_TESTRUN_FK='+FRunID+';';
  994. Q.ExecSQL;
  995. Q.SQL.Text:='INSERT INTO tr2 SELECT * FROM TESTRESULTS '+
  996. 'WHERE TR_TESTRUN_FK='+FCompareRunID+';';
  997. Q.ExecSQL;
  998. S:='SELECT T_ID as Id,T_NAME as Filename,tr1.TR_SKIP as Run1_Skipped,'
  999. +'tr2.TR_SKIP as Run2_Skipped,tr1.TR_OK as Run1_OK,'
  1000. +'tr2.TR_OK as Run2_OK, tr1.TR_Result as Run1_Result,'
  1001. +'tr2.TR_RESULT as Run2_Result '
  1002. +'FROM TESTS, tr2 LEFT JOIN tr1 USING (TR_TEST_FK) '
  1003. +'WHERE ((tr1.TR_SKIP IS NULL) or'
  1004. +' (tr2.TR_SKIP IS NULL) or '
  1005. +' (%s (tr1.TR_Result<>tr2.TR_Result)))'
  1006. +'and (T_ID=tr2.TR_TEST_FK)';
  1007. If FNoSkipped then
  1008. begin
  1009. Qry:='(((tr1.TR_SKIP="+") and (tr2.TR_OK="-") and (tr2.TR_SKIP="-")) or '
  1010. +'((tr1.TR_OK="-") and (tr1.TR_SKIP="-") and (tr2.TR_SKIP="+")) or '
  1011. +'((tr1.TR_SKIP="-") and (tr2.TR_SKIP="-"))) and ';
  1012. end
  1013. else
  1014. Qry:='';
  1015. Qry:=Format(S,[Qry]);
  1016. If FDebug then
  1017. begin
  1018. Writeln('Query: '+Qry);
  1019. Flush(stdout);
  1020. end;
  1021. FRunCount:=0;
  1022. FRunSkipCount:=0;
  1023. FRunFailedCount:=0;
  1024. Q.SQL.Text:=Qry;
  1025. With Q do
  1026. try
  1027. Open;
  1028. Try
  1029. With CreateTableProducer(Q) do
  1030. Try
  1031. Border:=True;
  1032. FL:='Filename,Run1_OK,Run2_OK';
  1033. If Not FNoSkipped then
  1034. FL:=FL+',Run1_Skipped,Run2_Skipped';
  1035. FL:=FL+',Run1_Result,Run2_Result';
  1036. CreateColumns(FL);
  1037. OnGetRowAttributes:=@GetRunRowAttr;
  1038. TableColumns.ColumnByNAme('Run1_Result').OnGetCellContents:=
  1039. @FormatTestResult;
  1040. TableColumns.ColumnByNAme('Run2_Result').OnGetCellContents:=
  1041. @FormatTestResult;
  1042. TableColumns.ColumnByNAme('Filename').OnGetCellContents:=
  1043. @FormatFileDetails;
  1044. //(TableColumns.Items[0] as TTableColumn).ActionURL:=ALink;
  1045. CreateTable(Response);
  1046. Finally
  1047. Free;
  1048. end;
  1049. Writeln('<p>Record count: ',Q.RecordCount,'</p>');
  1050. Finally
  1051. Close;
  1052. end;
  1053. finally
  1054. Free;
  1055. end;
  1056. If Not (FRunCount=0) and not (FNoSkipped or FOnlyFailed) then
  1057. begin
  1058. ParaGraphStart;
  1059. TagStart('IMG',Format('Src="'+TestsuiteCGIURL+'?action=2&pietotal=%d&piefailed=%d&pieskipped=%d"',[FRunCount,FRunFailedCount,FRunSkipCount]));
  1060. end;
  1061. end
  1062. else
  1063. Write('No data for test run with ID: '+FRunID);
  1064. end;
  1065. end;
  1066. procedure TTestSuite.GetRunRowAttr(Sender: TObject; var BGColor: String;
  1067. var Align: THTMLAlign; var VAlign: THTMLValign; var CustomAttr: String);
  1068. Var
  1069. P : TTableProducer;
  1070. Skip1Field, Skip2Field, Run1Field, Run2Field : TField;
  1071. begin
  1072. P:=(Sender as TTAbleProducer);
  1073. Inc(FRunCount);
  1074. If (FOnlyFailed and FNoSkipped) then
  1075. begin
  1076. If (P.CurrentRow Mod 2)=0 then
  1077. BGColor:='#EEEEEE'
  1078. end
  1079. else
  1080. begin
  1081. Skip1Field := P.Dataset.FindField('Skipped');
  1082. if Skip1Field = nil then
  1083. begin
  1084. Skip1Field := P.Dataset.FindField('Run1_Skipped');
  1085. Skip2Field := P.Dataset.FindField('Run2_Skipped');
  1086. end
  1087. else
  1088. Skip2Field := nil;
  1089. Run1Field := P.Dataset.FindField('OK');
  1090. if Run1Field = nil then
  1091. Run1Field := P.Dataset.FindField('Run1_OK');
  1092. Run2Field := P.Dataset.FindField('OK');
  1093. if Run2Field = nil then
  1094. Run2Field := P.Dataset.FindField('Run2_OK');
  1095. If (not FNoSkipped) and ((Skip1Field.AsString='+')
  1096. or ((Skip2Field <> nil) and (Skip2Field.AsString = '+'))) then
  1097. begin
  1098. Inc(FRunSkipCount);
  1099. BGColor:='yellow'; // Yellow
  1100. end
  1101. else If Run2Field.AsString='+' then
  1102. begin
  1103. if Run1Field.AsString='' then
  1104. BGColor:='#68DFB8'
  1105. else if Run1Field.ASString<>'+' then
  1106. BGColor:='#98FB98'; // pale Green
  1107. end
  1108. else if Run2Field.AsString='-' then
  1109. begin
  1110. Inc(FRunFailedCount);
  1111. if Run1Field.AsString='' then
  1112. BGColor:='#FF82AB' // Light red
  1113. else if Run1Field.AsString<>'-' then
  1114. BGColor:='#FF225B';
  1115. end;
  1116. end;
  1117. end;
  1118. procedure TTestSuite.FormatFailedOverview(Sender: TObject; var CellData: String);
  1119. Var
  1120. S: String;
  1121. P : TTableProducer;
  1122. begin
  1123. P:=(Sender as TTableProducer);
  1124. S:=Format(SDetailsURL,[P.DataSet.FieldByName('ID').AsString]);
  1125. S:=S+'&failedonly=1&noskipped=1';
  1126. CellData:=Format('<A HREF="%s">%s</A>',[S,CellData]);
  1127. end;
  1128. procedure TTestSuite.FormatTestRunOverview(Sender: TObject; var CellData: String);
  1129. Var
  1130. S: String;
  1131. P : TTableProducer;
  1132. begin
  1133. P:=(Sender as TTableProducer);
  1134. S:=Format(SDetailsURL,[P.DataSet.FieldByName('TR_TESTRUN_FK').AsString]);
  1135. if FOnlyFailed then
  1136. S:=S+'&failedonly=1';
  1137. if FNoSkipped then
  1138. S:=S+'&noskipped=1';
  1139. CellData:=Format('<A HREF="%s">%s</A>',[S,CellData]);
  1140. end;
  1141. procedure TTestSuite.FormatFileDetails(Sender: TObject; var CellData: String);
  1142. Var
  1143. S: String;
  1144. P : TTableProducer;
  1145. begin
  1146. P:=(Sender as TTableProducer);
  1147. if FCompareRunID<>'' then
  1148. S:=Format(TestSuiteCGIURL + '?action=3&run1id=%s&run2id=%s&testfileid=%s',
  1149. [FRunID,FCompareRunID,P.DataSet.FieldByName('Id').AsString])
  1150. else
  1151. S:=Format(TestSuiteCGIURL + '?action=3&run1id=%s&testfileid=%s',
  1152. [FRunID,P.DataSet.FieldByName('Id').AsString]);
  1153. CellData:=Format('<A HREF="%s">%s</A>',[S,CellData]);
  1154. end;
  1155. procedure TTestSuite.FormatTestResult(Sender: TObject; var CellData: String);
  1156. Var
  1157. Res : longint;
  1158. Error:word;
  1159. TS : TTestStatus;
  1160. begin
  1161. Val(CellData,Res,Error);
  1162. if (Error=0) and (Res>=longint(FirstStatus)) and
  1163. (Res<=longint(LastStatus)) then
  1164. begin
  1165. TS:=TTestStatus(Res);
  1166. CellData:=StatusText[TS];
  1167. end;
  1168. end;
  1169. Procedure TTestSuite.CreateRunPie;
  1170. Var
  1171. I : TFPMemoryImage;
  1172. M : TMemoryStream;
  1173. begin
  1174. ftFont.InitEngine;
  1175. FontMgr.SearchPath:='/usr/lib/X11/fonts/truetype';
  1176. I:=TFPMemoryImage.Create(320,320);
  1177. try
  1178. If FRunCount=0 Then
  1179. Raise Exception.Create('Invalid parameters passed to script: No total count');
  1180. DoDrawPie(I,FRunSkipCount,FRunFailedCount,FRunCount);
  1181. M:=TMemoryStream.Create;
  1182. Try
  1183. With TFPWriterPNG.Create do
  1184. try
  1185. UseAlpha:=True;
  1186. ImageWrite(M,I);
  1187. Finally
  1188. Free;
  1189. end;
  1190. ContentType:='image/png';
  1191. EmitContentType;
  1192. M.Position:=0;
  1193. Response.CopyFrom(M,M.Size);
  1194. Finally
  1195. M.Free;
  1196. end;
  1197. Finally
  1198. I.Free;
  1199. end;
  1200. end;
  1201. Procedure TTestSuite.DoDrawPie(Img : TFPCustomImage; Skipped,Failed,Total : Integer);
  1202. Var
  1203. Cnv : TFPImageCanvas;
  1204. W,H,FH,CR,ra : Integer;
  1205. A1,A2,FR,SR,PR : Double;
  1206. R : TRect;
  1207. F : TFreeTypeFont;
  1208. Procedure AddPie(X,Y,R : Integer; AStart,AStop : Double; Col : TFPColor);
  1209. Var
  1210. DX,Dy : Integer;
  1211. begin
  1212. DX:=Round(R*Cos(A1));
  1213. DY:=Round(R*Sin(A1));
  1214. Cnv.Line(X,Y,X+DX,Y-DY);
  1215. DX:=Round(Ra*Cos(A2));
  1216. DY:=Round(Ra*Sin(A2));
  1217. Cnv.Line(X,Y,X+DX,Y-Dy);
  1218. DX:=Round(R/2*Cos((A1+A2)/2));
  1219. DY:=Round(R/2*Sin((A1+A2)/2));
  1220. Cnv.Brush.FpColor:=Col;
  1221. Cnv.FloodFill(X+DX,Y-DY);
  1222. end;
  1223. Function FractionAngle(F,T : Integer): Double;
  1224. begin
  1225. Result:=(2*Pi*(F/T))
  1226. end;
  1227. begin
  1228. F:=TFreeTypeFont.Create;
  1229. With F do
  1230. begin
  1231. Name:='arial';
  1232. FontIndex:=0;
  1233. Size:=12;
  1234. FPColor:=colred;
  1235. AntiAliased:=False;
  1236. Resolution:=96;
  1237. end;
  1238. // Writeln('Creating image');
  1239. Cnv:=TFPImageCanvas.Create(Img);
  1240. // Writeln('Getting width and height');
  1241. W:=Img.Width;
  1242. H:=Img.Height;
  1243. // Writeln('Transparant');
  1244. cnv.Brush.Style:=bsSolid;
  1245. cnv.Brush.FPColor:=colTransparent;
  1246. cnv.Pen.FPColor:=colWhite;
  1247. Cnv.Rectangle(0,0,W,H);
  1248. // Writeln('Setting font');
  1249. Cnv.Font:=F;
  1250. // Writeln('Getting textwidth ');
  1251. FH:=CNV.GetTextHeight('A');
  1252. If FH=0 then
  1253. FH:=14; // 3 * 14;
  1254. Inc(FH,3);
  1255. R.Top:=FH*4;
  1256. R.Left:=0;
  1257. R.Bottom:=H;
  1258. CR:=H-(FH*4);
  1259. If W>CR then
  1260. R.Right:=CR
  1261. else
  1262. R.Right:=W;
  1263. Ra:=CR div 2;
  1264. // Writeln('Setting pen color');
  1265. Cnv.Pen.FPColor:=colBlack;
  1266. // Writeln('Palette size : ',Img.Palette.Count);
  1267. // Writeln('Setting brush style');
  1268. cnv.brush.FPColor:=colRed;
  1269. // cnv.pen.width:=1;
  1270. // Writeln('Drawing ellipse');
  1271. Cnv.Ellipse(R);
  1272. // Writeln('Setting text');
  1273. // Writeln('Palette size : ',Img.Palette.Count);
  1274. cnv.font.FPColor:=colred;
  1275. Inc(FH,4);
  1276. FR:=Failed/Total;
  1277. SR:=Skipped/Total;
  1278. PR:=1-(FR+SR);
  1279. Cnv.Textout(1,FH,Format('%d Failed (%3.1f%%)',[Failed,Fr*100]));
  1280. // Writeln('Palette size : ',Img.Palette.Count);
  1281. cnv.font.FPColor:=colYellow;
  1282. Cnv.Textout(1,FH*2,Format('%d Skipped (%3.1f%%)',[Skipped,SR*100]));
  1283. A1:=(Pi*2*(failed/total));
  1284. A2:=A1+(Pi*2*(Skipped/Total));
  1285. AddPie(Ra,R.Top+Ra,Ra,A1,A2,ColYellow);
  1286. cnv.font.FPColor:=colGreen;
  1287. // Writeln('Palette size : ',Img.Palette.Count);
  1288. A1:=A2;
  1289. A2:=A1+(Pi*2*((Total-(Skipped+Failed))/Total));
  1290. Cnv.Textout(1,FH*3,Format('%d Passed (%3.1f%%',[Total-Skipped-Failed,PR*100]));
  1291. AddPie(Ra,R.Top+Ra,Ra,A1,A2,ColGreen);
  1292. // Writeln('Palette size : ',Img.Palette.Count);
  1293. // Writeln('All done');
  1294. end;
  1295. end.