tshttp.pp 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188
  1. unit tshttp;
  2. {$mode objfpc}
  3. {$h+}
  4. {$WARN 5024 off : Parameter "$1" not used}
  5. interface
  6. uses
  7. classes, httpdefs, fphttp, inifiles, types, sysutils,
  8. sqldb, whtml, db, dbwhtml,
  9. tsgraph, tsdb, tssql, tshistory, tstypes, tsconsts, tsutils, tshtml;
  10. Type
  11. { TTestSuite }
  12. TTestSuite = Class(TCustomHTTPModule)
  13. Private
  14. FResponse: TResponse;
  15. FTitle: String;
  16. FVars: TQueryData;
  17. FRunData : TTestRunData;
  18. FCompareRunData :TTestRunData;
  19. FPlatFormID : Integer;
  20. FHTMLWriter : TTestSuiteHtmlWriter;
  21. FSQL : TTestSQL;
  22. FConstructSQL : TTestSuiteSQL;
  23. FRunStats : TRunStats;
  24. FInfo : TDBInfo;
  25. FRequest : TRequest;
  26. FContent : TStream;
  27. procedure DoDetailURL(aRunID: Int64; aDate: TDateTime; out aURl: String);
  28. Procedure GetOverviewRowAttr(Sender : TObject; Var BGColor : String;
  29. Var Align : THTMLAlign; Var VAlign : THTMLValign;
  30. Var CustomAttr : String) ;
  31. Procedure GetRunRowAttr(Sender : TObject; Var BGColor : String;
  32. Var Align : THTMLAlign; Var VAlign : THTMLValign;
  33. Var CustomAttr : String) ;
  34. function CreateTestSQL: TTestSQL;
  35. function GetVersionControlURL: string;
  36. procedure ShowAllHistoryData(aQuery: TSQLQuery);
  37. procedure ShowLastLog(aRunID: Int64; aTestID, aPlatformID: Integer);
  38. procedure ShowSourceFile;
  39. procedure WriteTestInfo;
  40. Public
  41. constructor createnew(aOwner : TComponent; CreateMode: Integer); override;
  42. destructor destroy; override;
  43. procedure HandleRequest(ARequest: TRequest; AResponse: TResponse); override;
  44. Function InitCGIVars : Integer;
  45. Procedure DoRun; // override;
  46. Procedure ShowRunResults;
  47. Procedure ShowRunComparison;
  48. Procedure ShowOneTest;
  49. Procedure ShowHistory;
  50. Function ConnectToDB : Boolean;
  51. procedure DisconnectFromDB;
  52. Procedure ShowRunOverview;
  53. Procedure CreateRunPie;
  54. Function ShowRunData : Boolean;
  55. Procedure LDump(Const St : String);
  56. Procedure LDumpLn(Const St : String);
  57. Property Title : String Read FTitle Write FTitle;
  58. Property Request : TRequest Read FRequest;
  59. Property Response : TResponse Read FResponse;
  60. end;
  61. Procedure HandleTestSuiteRequest(aRequest : TRequest; aResponse : TResponse);
  62. implementation
  63. uses
  64. wformat,
  65. dateutils;
  66. Procedure HandleTestSuiteRequest(aRequest : TRequest; aResponse : TResponse);
  67. Var
  68. Suite : TTestSuite;
  69. begin
  70. Suite:=TTestSuite.CreateNew(Nil);
  71. try
  72. Suite.Title:='Free Pascal Compiler Test Suite Results';
  73. Suite.HandleRequest(aRequest,aResponse);
  74. aResponse.SendResponse;
  75. finally
  76. Suite.Free;
  77. end;
  78. end;
  79. procedure TTestSuite.DoRun;
  80. var
  81. lAction : integer;
  82. begin
  83. // Terminate;
  84. Try
  85. ConnectToDB;
  86. lAction:=InitCGIVars;
  87. if (FVars.RunID>0) and not FSQL.GetRunData(FVars.RunID,FRunData) then
  88. FRunData.RunID:=-1;
  89. if (FVars.CompareRunID>0) and not FSQL.GetRunData(FVars.CompareRunID,FCompareRunData) then
  90. FCompareRunData.RunID:=-1;
  91. Case lAction of
  92. faction_show_overview :
  93. begin
  94. FHTMLWriter.EmitOverviewForm(Title);
  95. ShowRunOverview;
  96. end;
  97. faction_show_run_results :
  98. if (FVars.CompareRunID<=0) then
  99. ShowRunResults
  100. else
  101. ShowRunComparison;
  102. faction_show_run_pie : CreateRunPie;
  103. faction_show_one_test : ShowOneTest;
  104. faction_show_history : ShowHistory;
  105. faction_compare_with_previous :
  106. begin
  107. FVars.CompareRunID:=FVars.RunID;
  108. FVars.RunID:=FVars.PreviousRunID;
  109. ShowRunComparison;
  110. end;
  111. faction_compare_with_next :
  112. begin
  113. FVars.CompareRunID:=FVars.NextRunID;
  114. ShowRunComparison;
  115. end;
  116. faction_compare2_with_previous :
  117. begin
  118. FVars.RunID:=FVars.Previous2RunID;
  119. ShowRunComparison;
  120. end;
  121. faction_compare2_with_next :
  122. begin
  123. FVars.RunID:=FVars.CompareRunID;
  124. FVars.CompareRunID:=FVars.Next2RunID;
  125. ShowRunComparison;
  126. end;
  127. faction_compare_both_with_previous :
  128. begin
  129. FVars.RunID:=FVars.PreviousRunID;
  130. FVars.CompareRunID:=FVars.Previous2RunID;
  131. ShowRunComparison;
  132. end;
  133. faction_compare_both_with_next :
  134. begin
  135. FVars.RunID:=FVars.NextRunID;
  136. FVars.CompareRunID:=FVars.Next2RunID;
  137. ShowRunComparison;
  138. end;
  139. end;
  140. finally
  141. FHTMLWriter.EmitEnd;
  142. DisConnectFromDB;
  143. end;
  144. end;
  145. function TTestSuite.InitCGIVars: Integer;
  146. var
  147. L : TStrings;
  148. begin
  149. TestsuiteCGIURL:=Request.ScriptName;
  150. DateSeparator:='/';
  151. L:=TStringList.Create;
  152. try
  153. FVars.InitFromVars(FSQL,Request.QueryFields);
  154. finally
  155. L.Free;
  156. end;
  157. Result:=FVars.Action;
  158. SDetailsURL := TestsuiteCGIURL + '?action=1&amp;run1id=%s';
  159. end;
  160. procedure TTestSuite.DoDetailURL(aRunID: Int64; aDate: TDateTime; out aURl: String);
  161. var
  162. lDate : String;
  163. begin
  164. if aDate=0 then
  165. lDate:='never'
  166. else
  167. lDate:=DateToStr(aDate);
  168. aURL:=Self.FHTMLWriter.FormatDetailURL(IntToStr(aRunID),lDate);
  169. end;
  170. function TTestSuite.CreateTestSQL : TTestSQL;
  171. var
  172. aIni : TCustomIniFile;
  173. lPort : Integer;
  174. lHostName,lDatabaseName,lUserName,lPassword : String;
  175. begin
  176. Result:=Nil;
  177. aIni:=TMemIniFile.Create(DefaultDBConfigFileName);
  178. try
  179. With aIni do
  180. begin
  181. lHostName:=ReadString(SSection,KeyHost,'localhost');
  182. lDatabaseName:=ReadString(SSection,KeyName,'testsuite');
  183. lUserName:=ReadString(SSection,KeyUser,'');
  184. lPassword:=ReadString(SSection,KeyPassword,'');
  185. lPort:=ReadInteger(SSection,KeyPort,0);
  186. end;
  187. finally
  188. aIni.Free;
  189. end;
  190. if (lHostName='') or (lDatabaseName='') or (lUserName='') or (lPassword='') then
  191. exit;
  192. Result:=TTestSQL.create(lDatabaseName,lHostName,lUserName,lPassword,lPort);
  193. end;
  194. constructor TTestSuite.createnew(aOwner: TComponent; CreateMode: Integer);
  195. begin
  196. inherited createNew(aOwner,CreateMode);
  197. FSQL:=CreateTestSQL;
  198. FInfo:=TDBInfo.Create;
  199. FVars:=TQueryData.Create;
  200. FConstructSQL:=TTestSuiteSQL.create(FVars,FSQL,FInfo);
  201. FContent:=TMemoryStream.Create;
  202. FHtmlWriter:=TTestSuiteHTMLWriter.Create(FContent,FSQL,FVars);
  203. OnVerbose:[email protected];
  204. end;
  205. destructor TTestSuite.destroy;
  206. begin
  207. OnVerbose:=Nil;
  208. FreeAndNil(FContent);
  209. FreeAndNil(FConstructSQL);
  210. FreeAndNil(FInfo);
  211. FreeAndNil(FVars);
  212. FreeAndNil(FSQL);
  213. inherited destroy;
  214. end;
  215. procedure TTestSuite.HandleRequest(ARequest: TRequest; AResponse: TResponse{; var AHandled: Boolean});
  216. begin
  217. FRequest:=aRequest;
  218. FResponse:=aResponse;
  219. try
  220. DoRun;
  221. aResponse.ContentStream:=FContent;
  222. finally
  223. FRequest:=Nil;
  224. FResponse:=Nil;
  225. end;
  226. end;
  227. function TTestSuite.ConnectToDB: Boolean;
  228. begin
  229. Result:=False;
  230. Result:=FSQL.ConnectToDatabase;
  231. if not Result then
  232. exit;
  233. FInfo.AllCategoryID:=FSQL.GetCategoryID('All');
  234. FInfo.AllOSID:=FSQL.GetOSID('All');
  235. FInfo.AllCPUID:=FSQL.GetCPUID('All');
  236. FInfo.AllVersionID:=FSQL.GetVersionID('All');
  237. if FVars.OSID <= 0 then
  238. FVars.OSID:=FInfo.AllOSID;
  239. if FVars.CPUID<=0 then
  240. FVars.CPUID:=FInfo.AllCPUID;
  241. if FVars.VersionID<=0 then
  242. FVars.VersionID:=FInfo.AllVersionID;
  243. end;
  244. procedure TTestSuite.LDump(const St: String);
  245. var
  246. ShortS : ShortString;
  247. i,p : longint;
  248. begin
  249. i:=length(St);
  250. p:=1;
  251. while (i>255) do
  252. begin
  253. ShortS:=copy(St,p,255);
  254. inc(p,255);
  255. dec(i,255);
  256. FHTMLWriter.Dump(ShortS);
  257. end;
  258. ShortS:=Copy(St,p,255);
  259. FHTMLWriter.Dump(ShortS);
  260. end;
  261. procedure TTestSuite.LDumpLn(const St: String);
  262. begin
  263. LDump(St);
  264. LDump(LineFeed);
  265. end;
  266. procedure TTestSuite.DisconnectFromDB;
  267. begin
  268. If Assigned(FSQL) then
  269. begin
  270. FSQL.DisconnectDatabase;
  271. FreeAndNil(FSQL);
  272. end;
  273. end;
  274. procedure TTestSuite.GetOverviewRowAttr(Sender: TObject; var BGColor: String;
  275. var Align: THTMLAlign; var VAlign: THTMLValign; var CustomAttr: String);
  276. begin
  277. If ((Sender as TTAbleProducer).CurrentRow mod 2=0) then
  278. BGColor:='#EEEEEE'
  279. end;
  280. procedure TTestSuite.ShowRunOverview;
  281. var
  282. Qry : String;
  283. Q : TSQLQuery;
  284. A : String;
  285. lTable : TTableProducer;
  286. begin
  287. A:=SDetailsURL;
  288. If FVars.OnlyFailed then
  289. A:=A+'&amp;failedonly=1';
  290. If FVars.NoSkipped then
  291. A:=A+'&amp;noskipped=1';
  292. Qry:=FConstructSQL.GetRunOverviewSQL;
  293. If FVars.Debug then
  294. Writeln('Query : '+Qry);
  295. lTable:=Nil;
  296. Q:=FSQL.CreateQuery(Qry);
  297. try
  298. Q.Open;
  299. lTable:=FHTMLWriter.CreateTableProducer(Q);
  300. lTable.Border:=True;
  301. lTable.OnGetRowAttributes:=@GetOverViewRowAttr;
  302. lTable.CreateColumns(Nil);
  303. With lTable.TableColumns do
  304. begin
  305. ColumnByName('ID').ActionURL:=A;
  306. ColumnByName('Failed').OnGetCellContents:[email protected];
  307. ColumnByName('rev').OnGetCellContents:[email protected];
  308. ColumnByName('comprev').OnGetCellContents:[email protected];
  309. ColumnByName('rtlrev').OnGetCellContents:[email protected];
  310. ColumnByName('packrev').OnGetCellContents:[email protected];
  311. ColumnByName('testsrev').OnGetCellContents:[email protected];
  312. end;
  313. lTable.CreateTable(FContent);
  314. FHTMLWriter.DumpLn(Format('<p>Record count: %d</p>',[Q.RecordCount]));
  315. finally
  316. lTable.Free;
  317. Q.Free;
  318. end;
  319. end;
  320. function TTestSuite.ShowRunData: Boolean;
  321. procedure EmitOneRow(RowTitle,FieldLeft,FieldRight : String; is_same : boolean);
  322. var
  323. FieldColor : string;
  324. begin
  325. if (FieldRight='') then
  326. FieldColor:=''
  327. else if is_same then
  328. FieldColor:='style="color:green;"'
  329. else
  330. FieldColor:='style="color:red;"';
  331. With FHTMLWriter do
  332. begin
  333. RowNext;
  334. if FieldColor<>'' then
  335. begin
  336. TagStart('TD',FieldColor);
  337. end
  338. else
  339. CellStart;
  340. LDumpLn(RowTitle);
  341. if FieldColor<>'' then
  342. begin
  343. CellEnd;
  344. TagStart('TD',FieldColor);
  345. end
  346. else
  347. CellNext;
  348. LDumpLn(FieldLeft);
  349. if FieldColor<>'' then
  350. begin
  351. CellEnd;
  352. TagStart('TD',FieldColor);
  353. end
  354. else
  355. CellNext;
  356. LDumpLn(FieldRight);
  357. CellEnd;
  358. end;
  359. end;
  360. procedure EmitOneRow(RowTitle,FieldLeft,FieldRight : String);
  361. var
  362. is_same : boolean;
  363. begin
  364. is_same:=(FieldLeft=FieldRight);
  365. EmitOneRow(RowTitle,FieldLeft,FieldRight,is_same);
  366. end;
  367. var
  368. aData,aCompData : TTestRunData;
  369. AddNewPar : Boolean;
  370. procedure EmitRow(RowTitle,FieldName : String);
  371. var
  372. FieldLeft, FieldRight : String;
  373. begin
  374. FieldLeft:=aData.GetField(FieldName);
  375. if aCompData.RunID>0 then
  376. FieldRight:=aCompData.GetField(FieldName)
  377. else
  378. FieldRight:='';
  379. EmitOneRow(RowTitle,FieldLeft,FieldRight);
  380. end;
  381. procedure MaybeEmitButton(const aVar,aValue : String; aCondition : boolean);
  382. begin
  383. if not aCondition then exit;
  384. FHTMLWriter.EmitSubmitButton(aVar,aValue);
  385. AddNewPar:=True;
  386. end;
  387. procedure CheckPar;
  388. begin
  389. if not AddNewPar then exit;
  390. FHTMLWriter.ParagraphEnd;
  391. FHTMLWriter.ParaGraphStart;
  392. end;
  393. Var
  394. isComp : Boolean;
  395. FLeft,FRight : string;
  396. Date1, Date2 : String;
  397. lNextRunID,lNext2RunID : Int64;
  398. lPreviousRunID,lPrevious2RunID : Int64;
  399. same_date : boolean;
  400. CompilerDate1, CompilerDate2 : string;
  401. begin
  402. lNextRunID:=-1;
  403. lNext2RunID:=-1;
  404. lPreviousRunID:=-1;
  405. lPrevious2RunID:=-1;
  406. Result:=(FVars.RunID<>-1);
  407. If not Result then
  408. exit;
  409. if Not FSQL.GetRunData(FVars.RunID,aData) then
  410. exit;
  411. isComp:=FVars.CompareRunID>0;
  412. if isComp and Not FSQL.GetRunData(FVars.CompareRunID,aCompData) then
  413. exit;
  414. With FHTMLWriter do
  415. begin
  416. FormStart(TestsuiteCGIURL,'get');
  417. TableStart(3,true);
  418. RowStart;
  419. CellStart;
  420. DumpLn('Run ID:');
  421. CellNext;
  422. EmitInput('run1id',IntToStr(FVars.RunID));
  423. CellNext;
  424. EmitInput('run2id',IntToStr(FVars.CompareRunID));
  425. CellEnd;
  426. EmitRow('Operating system:','os');
  427. EmitRow('Processor:','cpu');
  428. EmitRow('Version:','VERSION');
  429. if Not IsComp then
  430. FRight:=''
  431. else
  432. begin
  433. FRight:=aCompData.GetField('Failed')+
  434. '/'+aCompData.GetField('Ok')+
  435. '/'+aCompData.GetField('Total');
  436. end;
  437. EmitOneRow('Fails/OK/Total:',
  438. aData.GetField('Failed')+
  439. '/'+aData.GetField('Ok')+
  440. '/'+aData.GetField('Total'),
  441. FRight);
  442. EmitRow('Version:','Version');
  443. EmitRow('Full version:','CompilerFullVersion');
  444. EmitRow('Config:','Config');
  445. EmitRow('Machine:','Machine');
  446. if (FVars.CategoryID>0) then
  447. EmitRow('Category:','TU_CATEGORY_FK');
  448. If (FVars.CategoryID=1) then
  449. begin
  450. FLeft:=aData.GetField('rev');
  451. FormatSVNData(FLeft);
  452. if isComp then
  453. begin
  454. FRight:=aCompData.GetField('rev');
  455. FormatSVNData(FRight);
  456. end
  457. else
  458. FRight:='';
  459. EmitOneRow('SVN revisions:',FLeft,FRight);
  460. end;
  461. EmitRow('Submitter:','Submitter');
  462. Date1 := aData.GetField('Date');
  463. if Not IsComp then
  464. FRight:=''
  465. else
  466. begin
  467. Date2 := aCompData.GetField('Date');
  468. FRight:=Date2;
  469. end;
  470. same_date:=(date1=Date2);
  471. EmitOneRow('Date:',Date1,FRight,same_date);
  472. CompilerDate1 := aData.GetField('CompilerDate');
  473. if Not IsComp then
  474. FRight:=''
  475. else
  476. begin
  477. CompilerDate2 := aCompData.GetField('compilerdate');
  478. FRight:=CompilerDate2;
  479. end;
  480. same_date:=(CompilerDate1=CompilerDate2);
  481. EmitOneRow('CompilerDate:',CompilerDate1,FRight,same_date);
  482. lPreviousRunID:=FSQL.GetPreviousRunID(aData.RunID);
  483. EmitHiddenVar('previousrunid',lPreviousRunID);
  484. FLeft:=IntToStr(lPreviousRunID);
  485. if IsComp then
  486. begin
  487. lPrevious2RunID:=FSQL.GetPreviousRunID(FVars.CompareRunID);
  488. FRight:=IntToStr(lPrevious2RunID);
  489. EmitHiddenVar('previous2runid',lPrevious2RunID);
  490. end
  491. else
  492. FRight:='';
  493. EmitOneRow('Previous run:',FLeft,FRight);
  494. lNextRunID:=FSQL.GetNextRunID(FVars.RunID);
  495. EmitHiddenVar('nextrunid',lNextRunID);
  496. FLeft:=IntToStr(lNextRunID);
  497. if IsComp then
  498. begin
  499. lNext2RunID:=FSQL.GetNextRunID(FVars.CompareRunID);
  500. FRight:=IntToStr(lNext2RunID);
  501. EmitHiddenVar('next2runid',lNext2RunID);
  502. end;
  503. EmitOneRow('Next run:',FLeft,FRight);
  504. RowEnd;
  505. TableEnd;
  506. ParagraphStart;
  507. if FVars.Debug then
  508. EmitHiddenVar('DEBUGCGI', '1');
  509. EmitCheckBox('noskipped','1',FVars.NoSkipped);
  510. DumpLn(' Hide skipped tests');
  511. ParagraphEnd;
  512. ParagraphStart;
  513. EmitCheckBox('failedonly','1',FVars.onlyFailed);
  514. DumpLn(' Hide successful tests');
  515. ParagraphEnd;
  516. ParaGraphStart;
  517. AddNewPar:=false;
  518. MaybeEmitButton('action', 'Compare_to_previous', lPreviousRunID<>-1);
  519. MaybeEmitButton('action', 'Compare_to_next', (lNextRunID<>-1) and (lNextRunID <> FVars.CompareRunID));
  520. MaybeEmitButton('action', 'Compare_right_to_previous', (lPrevious2RunID<>-1) and (lPrevious2RunID <> FVars.RunID));
  521. MaybeEmitButton('action', 'Compare_right_to_next',lNext2RunID<>-1);
  522. CheckPar;
  523. MaybeEmitButton('action', 'Compare_both_to_previous', (lPrevious2RunID<>-1) and (lPreviousRunId<>-1));
  524. MaybeEmitButton('action', 'Compare_both_to_next', (lNext2RunID<>-1) and (lNextRunId<>-1));
  525. CheckPar;
  526. MaybeEmitButton('action','Show/Compare',True);
  527. MaybeEmitButton('action','View_history',FVars.TestFileID<>-1);
  528. EmitResetButton('','Reset form');
  529. ParagraphEnd;
  530. FormEnd;
  531. { give warning if dates reversed }
  532. if IsComp and (aData.Date > aCompData.Date) then
  533. begin
  534. ParagraphStart;
  535. DumpLn('Warning: testruns are not compared in chronological order.');
  536. ParagraphEnd;
  537. end;
  538. end;
  539. end;
  540. procedure TTestSuite.ShowRunResults;
  541. Var
  542. S : String;
  543. Qry : String;
  544. Q : TSQLQuery;
  545. FL : String;
  546. lTable : TTableProducer;
  547. begin
  548. Response.ContentType:='text/html';
  549. //EmitContentType;
  550. With FHTMLWriter do
  551. begin
  552. EmitDocType;
  553. EmitTitle(Title+' : Search Results');
  554. HeaderStart(1);
  555. DumpLn('Test suite results for run '+IntToStr(FVars.RunID));
  556. HeaderEnd(1);
  557. HeaderStart(2);
  558. DumpLn('Test run data : ');
  559. HeaderEnd(2);
  560. If not ShowRunData then
  561. begin
  562. DumpLn('No data for test run with ID: '+IntToStr(FVars.RunID));
  563. Exit;
  564. end;
  565. HeaderStart(2);
  566. DumpLn('ShowRunResults detailed test run results:');
  567. FL:='';
  568. If FVars.OnlyFailed or FVars.NoSkipped then
  569. begin
  570. FL:='';
  571. If FVars.OnlyFailed then
  572. FL:='successful';
  573. if FVars.NoSkipped then
  574. begin
  575. If (FL<>'') then
  576. FL:=FL+' and ';
  577. FL:=FL+'skipped';
  578. end;
  579. DumpLn(' ('+FL+' tests are hidden)');
  580. end;
  581. HeaderEnd(2);
  582. FPlatFormID:=FSQL.GetPlatformID(FVars.RunID);
  583. S:=Format(SQLSelectTestResults,[FVars.RunID,FPlatformID]);
  584. If FVars.OnlyFailed then
  585. S:=S+' AND (not TR_OK)';
  586. If FVars.NoSkipped then
  587. S:=S+' AND (not TR_SKIP)';
  588. S:=S+' ORDER BY T_ID ';
  589. Qry:=S;
  590. If FVars.Debug then
  591. begin
  592. ParaGraphStart;
  593. Dumpln('Query : '+Qry);
  594. ParaGraphEnd;
  595. end;
  596. end;
  597. Q:=FSQL.CreateQuery(Qry);
  598. try
  599. Q.PacketRecords:=-1;
  600. Q.Open;
  601. FHTMLWriter.DumpLn(Format('<p>Record count: %d </p>',[Q.RecordCount]));
  602. FL:='Id,Filename';
  603. If Not FVars.NoSkipped then
  604. FL:=FL+',Skipped';
  605. If Not FVars.OnlyFailed then
  606. FL:=FL+',OK';
  607. FL:=FL+',Result';
  608. lTable:=FHTMLWriter.CreateTableProducer(Q);
  609. lTable.Border:=True;
  610. lTable.CreateColumns(FL);
  611. lTable.OnGetRowAttributes:=@GetRunRowAttr;
  612. With lTable.TableColumns do
  613. begin
  614. ColumnByName('Id').OnGetCellContents:[email protected];
  615. ColumnByName('Filename').OnGetCellContents:[email protected];
  616. ColumnByName('Result').OnGetCellContents:[email protected];
  617. end;
  618. lTable.CreateTable(FContent); //Response);
  619. finally
  620. lTable.Free;
  621. Q.Free;
  622. end;
  623. If Not (FRunStats.OKCount=0) and not (FVars.NoSkipped and FVars.OnlyFailed) then
  624. FHTMLWriter.EmitPieImage(FRunStats.OKCount,FRunStats.FailedCount,FRunStats.SkipCount);
  625. end;
  626. procedure TTestSuite.ShowOneTest;
  627. Var
  628. Qry : String;
  629. Q : TSQLQuery;
  630. Res : Boolean;
  631. lTable : TTableProducer;
  632. begin
  633. Response.ContentType:='text/html';
  634. // EmitContentType;
  635. With FHTMLWriter do
  636. begin
  637. EmitDocType;
  638. EmitTitle(Title+' : File '+FVars.TestFileName+' Results');
  639. HeaderStart(1);
  640. DumpLn('Test suite results for test file '+FVars.TestFileName);
  641. HeaderEnd(1);
  642. HeaderStart(2);
  643. DumpLn('Test run data : ');
  644. HeaderEnd(2);
  645. if FVars.RunID<>-1 then
  646. Res:=ShowRunData
  647. else
  648. Res:=True;
  649. If not Res then
  650. begin
  651. DumpLn(Format('No data for test file with ID: %s',[FVars.TestFileID]));
  652. exit;
  653. end;
  654. WriteTestInfo;
  655. Qry:=FConstructSQL.GetSimpleTestResultsSQL;
  656. If FVars.Debug then
  657. begin
  658. ParaGraphStart;
  659. Dumpln('Query : '+Qry);
  660. ParaGraphEnd;
  661. end;
  662. FRunStats:=Default(TRunStats);
  663. lTable:=nil;
  664. Q:=FSQL.CreateQuery(Qry);
  665. try
  666. Q.Open;
  667. lTable:=CreateTableProducer(Q);
  668. lTable.Border:=True;
  669. lTable.CreateColumns(Nil);
  670. With lTable.TableColumns do
  671. begin
  672. Delete(ColumnByName('TR_TEST_FK').Index);
  673. ColumnByName('RUN').OnGetCellContents:=@FormatTestRunOverview;
  674. ColumnByName('TR_RESULT').OnGetCellContents:=@FormatTestResult;
  675. end;
  676. lTable.CreateTable(FContent); // Response);
  677. ParaGraphStart;
  678. DumpLn(Format('Record count: %d',[Q.RecordCount]));
  679. ParaGraphEnd;
  680. finally
  681. lTable.Free;
  682. Q.Free;
  683. end;
  684. if FVars.RunId<>-1 then
  685. ShowLastLog(FVars.RunId,fvars.testfileid,FRunData.PlatformID);
  686. if FVars.CompareRunId<>-1 then
  687. ShowLastLog(FVars.CompareRunId,fvars.testfileid,FRunData.PlatformID);
  688. if FVars.Debug then
  689. DumpLn(Format('After Log. Run ID: %d, Testfile ID: %d',[fvars.RunID, fvars.testfileid]));
  690. ShowSourceFile;
  691. end;
  692. end;
  693. procedure TTestSuite.ShowLastLog(aRunID : Int64; aTestID,aPlatformID : Integer);
  694. var
  695. LLog : String;
  696. begin
  697. LLog:=FSQL.StringQuery(Format('select TR_LOG from TESTLASTRESULTS left join testresults on (TL_TESTRESULTS_FK=TR_ID) where (TR_TEST_FK=%d) and (TL_PLATFORM_FK=%d)',[aTestID,aPlatformID]));
  698. With FHTMLWriter do
  699. if LLog='' then
  700. begin
  701. HeaderStart(2);
  702. DumpLn(Format('No log of %s on run %d:',[FVars.TestFileName,aRunId]));
  703. HeaderEnd(2);
  704. end
  705. else
  706. begin
  707. HeaderStart(2);
  708. DumpLn(Format('Log of %s on run %d:',[FVars.TestFileName,aRunID]));
  709. HeaderEnd(2);
  710. PreformatStart;
  711. Dump(LLog);
  712. PreformatEnd;
  713. end;
  714. end;
  715. procedure TTestSuite.WriteTestInfo;
  716. var
  717. lTestInfo : TTestInfo;
  718. begin
  719. With FHTMLWriter do
  720. begin
  721. HeaderStart(2);
  722. DumpLn('Test file "'+FVars.TestFileName+'" information:');
  723. HeaderEnd(2);
  724. ParaGraphStart;
  725. if (FVars.TestFileID<>-1) and FSQL.GetTestInfo(FVars.TestFileID,lTestInfo) then
  726. DumpTestInfo(lTestInfo);
  727. ParaGraphEnd;
  728. HeaderStart(2);
  729. DumpLn('WriteTestInfo detailed test run results:');
  730. HeaderEnd(2);
  731. end;
  732. end;
  733. procedure TTestSuite.ShowHistory;
  734. Var
  735. Res : Boolean;
  736. Qry : String;
  737. Q : TSQLQuery;
  738. TS : TTestStatus;
  739. lHistory : TTestHistoryInfo;
  740. lOSMap,lCPUMap,lVersionMap : TIntegerDynArray;
  741. lTable : TTableProducer;
  742. begin
  743. // Res:=False;
  744. Response.ContentType:='text/html';
  745. // EmitContentType;
  746. lTable:=nil;
  747. Q:=Nil;
  748. try
  749. With FHTMLWriter do
  750. begin
  751. EmitDocType;
  752. if FVars.TestFileName<>'' then
  753. EmitTitle(Title+' : File '+FVars.TestFileName+' Results')
  754. else
  755. EmitTitle(Title+' : History overview');
  756. if FVars.TestFileName<>'' then
  757. begin
  758. HeaderStart(1);
  759. DumpLn('Test suite results for test file '+FVars.TestFileName);
  760. HeaderEnd(1);
  761. HeaderStart(2);
  762. DumpLn('Test run data : ');
  763. HeaderEnd(2);
  764. end;
  765. if FVars.RunID<>-1 then
  766. Res:=ShowRunData
  767. else
  768. begin
  769. EmitHistoryForm(Title);
  770. Res:=(FVars.TestFileID<>-1);
  771. if not Res then
  772. begin
  773. HeaderStart(2);
  774. if Trim(FVars.TestFileName) <> '' then
  775. DumpLn(Format('Error: No test files matching "%s" found.', [FVars.TestFileName]))
  776. else
  777. DumpLn('Error: Please specify a test file.');
  778. HeaderEnd(2);
  779. end;
  780. end;
  781. If not Res then
  782. exit;
  783. if (FVars.TestFileName<>'') then
  784. WriteTestInfo;
  785. ParaGraphStart;
  786. If FInfo.IsAllCPU(FVars.CPUID) then
  787. lCPUMap:=FSQL.CreateMap(mtCPU);
  788. If FInfo.IsAllOS(FVars.OSID) then
  789. lOSMap:=FSQL.CreateMap(mtOS);
  790. if FInfo.IsAllVersion(fVars.VersionID) then
  791. lVersionMap:=FSQL.CreateMap(mtVersion);
  792. lHistory:=TTestHistoryInfo.Create(FSQL,lOSMap,lCPUMap,lVersionMap);
  793. lHistory.OnGetDetailURL:=@DoDetailURL;
  794. Qry:=FConstructSQL.GetTestResultsSQL;
  795. If FVars.Debug then
  796. begin
  797. Writeln(system.stdout,'Query : '+Qry);
  798. system.Flush(system.stdout);
  799. end;
  800. FRunStats:=Default(TRunStats);
  801. Q:=FSQL.CreateQuery(Qry);
  802. Q.PacketRecords:=-1;
  803. Q.Open;
  804. lHistory.UpdateFromDataset(Q);
  805. DumpLn(Format('<p>Total = %d </p>',[lHistory.total_count]));
  806. if lHistory.Total_count > 0 then
  807. DumpLn(Format('<p>OK=%d Percentage= %3.2f </p>',[lHistory.OK_count,lHistory.OK_count*100/lHistory.total_count]));
  808. if lHistory.Skip_count > 0 then
  809. DumpLn(Format('<p>Skipped=%d Percentage= %3.2f </p>',[lHistory.Skip_count,lHistory.Skip_count*100/lHistory.total_count]));
  810. if lHistory.total_count>0 then
  811. begin
  812. TableStart(5,True);
  813. RowStart;
  814. CellStart;
  815. DumpLn('Result type');
  816. CellNext;
  817. DumpLn('Cat.');
  818. CellNext;
  819. DumpLn('Count');
  820. CellNext;
  821. DumpLn('Percentage');
  822. CellNext;
  823. DumpLn('First date');
  824. CellNext;
  825. DumpLn('Last Date');
  826. CellEnd;
  827. end;
  828. For TS:=FirstStatus to LastStatus do
  829. if lHistory.Result_count[TS]>0 then
  830. begin
  831. lHistory.WriteCounts(FHTMLWriter,TS);
  832. lHistory.WriteCPUHistory(FHTMLWriter,TS);
  833. lHistory.WriteOSHistory(FHTMLWriter,TS);
  834. lHIstory.WriteVersionHistory(FHTMLWriter,TS);
  835. end;
  836. if lHistory.total_count>0 then
  837. begin
  838. TableEnd;
  839. end;
  840. end; // FHTMLWriter;
  841. If FVars.Debug or FVars.ListAll then
  842. begin
  843. if Q.Active then
  844. Q.First
  845. else
  846. Q.Open;
  847. ShowAllHistoryData(Q);
  848. end;
  849. ShowSourceFile;
  850. Finally
  851. lTable.Free;
  852. Q.Free;
  853. end;
  854. end;
  855. procedure TTestSuite.ShowAllHistoryData(aQuery: TSQLQuery);
  856. var
  857. FL : String;
  858. lTable : TTableProducer;
  859. begin
  860. aQuery.First;
  861. FL:='Run,Date,OK,Skip,Result';
  862. if FVars.Submitter='' then
  863. FL:=FL+',Submitter';
  864. if FVars.Machine='' then
  865. FL:=FL+',Machine';
  866. if FVars.Config='' then
  867. FL:=FL+',Config';
  868. if (FVars.OSID=-1) or (FVars.OSID=FInfo.AllOSID) then
  869. FL:=FL+',OS';
  870. if (FVars.CPUID=-1) or (FVars.CPUID=FInfo.AllCPUID) then
  871. FL:=FL+',CPU';
  872. if (FVars.VersionID=-1) or (FVars.VersionID=FInfo.AllVersionID) then
  873. FL:=FL+',Version';
  874. FL:=FL+',Fails,CompDate';
  875. FL:=FL+',Tests_rev,RTL_rev,Compiler_rev,Packages_rev';
  876. lTable:=FHTMLWriter.CreateTableProducer(aQuery);
  877. try
  878. lTable.Border:=True;
  879. lTable.CreateColumns(FL);
  880. lTable.TableColumns.ColumnByName('RUN').OnGetCellContents:[email protected];
  881. lTable.TableColumns.ColumnByName('Result').OnGetCellContents:[email protected];
  882. lTable.CreateTable(FContent); //Response);
  883. finally
  884. lTable.Free
  885. end;
  886. end;
  887. function TTestSuite.GetVersionControlURL : string;
  888. var
  889. Base,lURL : String;
  890. ver : known_versions;
  891. Index : Integer;
  892. begin
  893. Base:='trunk';
  894. if FVars.VersionBranch<>'' then
  895. begin
  896. // Test all but last version, which is assumed to be trunk
  897. for ver:=low(known_versions) to pred(high(known_versions)) do
  898. if ver_string[ver]=FVars.VersionBranch then
  899. begin
  900. base:=ver_branch[ver];
  901. break;
  902. end;
  903. end;
  904. index:=pos('/',Base);
  905. if index>0 then
  906. Base:=Copy(Base,index+1,length(Base));
  907. if Base='trunk' then
  908. Base:='main';
  909. lURL:=ViewGitHashURL+Base;
  910. if FVars.CategoryID<=1 then
  911. lURL:=lURL+TestsSubDir
  912. else
  913. begin
  914. lURL:=lURL+DataBaseSubDir;
  915. // This assumes that type TAnyType is
  916. // defined in anytype.pas source PM
  917. if pos('/',FVars.TestFileName)>0 then
  918. FVars.Testfilename:=lowercase(copy(FVars.TestFilename,2,pos('/',FVars.TestFilename)-2)+'.pas');
  919. end;
  920. Result:=lURL;
  921. end;
  922. procedure TTestSuite.ShowSourceFile;
  923. var
  924. lFN,lUrl,Source : String;
  925. begin
  926. Source:='';
  927. lFn:=FVars.TestFileName;
  928. if (fvars.testfileid <> -1) then
  929. Source:=FSQL.GetTestSource(fvars.testfileid);
  930. With FHTMLWriter do
  931. begin
  932. if Source<>'' then
  933. begin
  934. HeaderStart(2);
  935. DumpLn('Source:');
  936. HeaderEnd(2);
  937. PreformatStart;
  938. Dumpln(Source);
  939. PreformatEnd;
  940. end;
  941. if (Source='') then
  942. DumpLn('<P>No Source in TestSuite DataBase.</P>');
  943. lURL:=GetVersionControlURL;
  944. HeaderStart(3);
  945. DumpLn('Link to Git view of '+
  946. '<A HREF="'+lURL+lFn+'?view=markup'+
  947. '" TARGET="fpc_source"> '+lFN+'</A> source. ');
  948. HeaderEnd(3);
  949. end;
  950. end;
  951. procedure TTestSuite.ShowRunComparison;
  952. Var
  953. Qry : String;
  954. Q : TSQLQuery;
  955. FL : String;
  956. lTable : TTableProducer;
  957. begin
  958. Response.ContentType:='text/html';
  959. // EmitContentType;
  960. With FHTMLWriter do
  961. begin
  962. EmitDocType;
  963. EmitTitle(Title+' : Compare 2 runs');
  964. HeaderStart(1);
  965. DumpLn(Format('Test suite results for run %d vs. %d',[FVars.RunID,FVars.CompareRunID]));
  966. HeaderEnd(1);
  967. HeaderStart(2);
  968. DumpLn('Test run data: ');
  969. HeaderEnd(2);
  970. If Not ShowRunData then
  971. begin
  972. DumpLn(Format('No data for test run with ID: %d',[FVars.RunID]));
  973. exit;
  974. end;
  975. HeaderStart(2);
  976. DumpLn('ShowRunComparison detailed test run results:');
  977. FL:='';
  978. If FVars.OnlyFailed or FVars.NoSkipped then
  979. begin
  980. FL:='';
  981. If FVars.OnlyFailed then
  982. FL:='successful';
  983. if FVars.NoSkipped then
  984. begin
  985. If (FL<>'') then
  986. FL:=FL+' and ';
  987. FL:=FL+'skipped';
  988. end;
  989. DumpLn(' ('+FL+' tests are hidden)');
  990. end;
  991. HeaderEnd(2);
  992. ParaGraphStart;
  993. end;
  994. Qry:=FConstructSQL.GetCompareRunSQL;
  995. If FVars.Debug then
  996. begin
  997. system.WriteLn('Query: '+Qry);
  998. system.Flush(stdout);
  999. end;
  1000. FRunStats:=Default(TRunStats);
  1001. Q:=FSQL.CreateQuery(Qry);
  1002. try
  1003. Q.Open;
  1004. FL:='Id,Filename,Run1_OK,Run2_OK';
  1005. If Not FVars.NoSkipped then
  1006. FL:=FL+',Run1_Skipped,Run2_Skipped';
  1007. FL:=FL+',Run1_Result,Run2_Result';
  1008. lTable:=FHTMLWriter.CreateTableProducer(Q);
  1009. lTable.Border:=True;
  1010. lTable.CreateColumns(FL);
  1011. lTable.OnGetRowAttributes:=@GetRunRowAttr;
  1012. With lTable.TableColumns do
  1013. begin
  1014. ColumnByName('Id').OnGetCellContents:[email protected];
  1015. ColumnByName('Run1_Result').OnGetCellContents:[email protected];
  1016. ColumnByName('Run2_Result').OnGetCellContents:[email protected];
  1017. ColumnByName('Filename').OnGetCellContents:[email protected];
  1018. end;
  1019. //(TableColumns.Items[0] as TTableColumn).ActionURL:=ALink;
  1020. lTable.CreateTable(FContent); // Response);
  1021. FHTMLWriter.DumpLn(format('<p>Record count: %d</P>',[Q.RecordCount]));
  1022. finally
  1023. lTable.Free;
  1024. Q.Free;
  1025. end;
  1026. If Not (FRunStats.OKCount=0) and not (FVars.NoSkipped and FVars.OnlyFailed) then
  1027. FHTMLWriter.EmitPieImage(FRunStats.OKCount,FRunStats.FailedCount,FRunStats.SkipCount);
  1028. end;
  1029. procedure TTestSuite.GetRunRowAttr(Sender: TObject; var BGColor: String;
  1030. var Align: THTMLAlign; var VAlign: THTMLValign; var CustomAttr: String);
  1031. Var
  1032. P : TTableProducer;
  1033. Skip1Field, Skip2Field, Run1Field, Run2Field : TField;
  1034. begin
  1035. P:=(Sender as TTableProducer);
  1036. Inc(FRunStats.OKCount);
  1037. If (FVars.OnlyFailed and FVars.NoSkipped) then
  1038. begin
  1039. If (P.CurrentRow Mod 2)=0 then
  1040. BGColor:='#EEEEEE'
  1041. end
  1042. else
  1043. begin
  1044. Skip1Field := P.Dataset.FindField('Skipped');
  1045. if Skip1Field = nil then
  1046. begin
  1047. Skip1Field := P.Dataset.FindField('Run1_Skipped');
  1048. Skip2Field := P.Dataset.FindField('Run2_Skipped');
  1049. end
  1050. else
  1051. Skip2Field := nil;
  1052. Run1Field := P.Dataset.FindField('OK');
  1053. if Run1Field = nil then
  1054. Run1Field := P.Dataset.FindField('Run1_OK');
  1055. Run2Field := P.Dataset.FindField('OK');
  1056. if Run2Field = nil then
  1057. Run2Field := P.Dataset.FindField('Run2_OK');
  1058. If (not FVars.NoSkipped) and ((Skip1Field.AsBoolean)
  1059. or ((Skip2Field <> nil) and (Skip2Field.AsBoolean))) then
  1060. begin
  1061. Inc(FRunStats.SkipCount);
  1062. BGColor:='yellow'; // Yellow
  1063. end
  1064. else If Run2Field.AsBoolean then
  1065. begin
  1066. if Run1Field.AsString='' then
  1067. BGColor:='#68DFB8'
  1068. else if Run1Field.AsBoolean then
  1069. BGColor:='#98FB98'; // pale Green
  1070. end
  1071. else if Not Run2Field.AsBoolean then
  1072. begin
  1073. Inc(FRunStats.FailedCount);
  1074. if Run1Field.AsString='' then
  1075. BGColor:='#FF82AB' // Light red
  1076. else if Not Run1Field.AsBoolean then
  1077. BGColor:='#FF225B';
  1078. end;
  1079. end;
  1080. end;
  1081. procedure TTestSuite.CreateRunPie;
  1082. Var
  1083. lGraph : TTestSuiteGraph;
  1084. begin
  1085. lGraph:=TTestSuiteGraph.Create(FVars);
  1086. try
  1087. If FVars.RunCount=0 Then
  1088. Raise Exception.Create('Invalid parameters passed to script: No total count');
  1089. lGraph.DrawPie(FContent,FVars.RunSkipCount,FVars.RunFailedCount,FVars.RunCount);
  1090. Response.ContentType:='image/png';
  1091. FContent.Position:=0;
  1092. Finally
  1093. lGraph.Free;
  1094. end;
  1095. end;
  1096. begin
  1097. ShortDateFormat:='yyyy/mm/dd';
  1098. end.