dbdigest.pp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
  1. {
  2. This file is part of the Free Pascal test suite.
  3. Copyright (c) 2002 by the Free Pascal development team.
  4. This program generates a digest
  5. of the last tests run.
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. {$mode objfpc}
  13. {$h+}
  14. program digest;
  15. uses
  16. sysutils,teststr,testu,dbtests;
  17. Type
  18. TTestStatus = (
  19. stFailedToCompile,
  20. stSuccessCompilationFailed,
  21. stFailedCompilationsuccessful,
  22. stSuccessfullyCompiled,
  23. stFailedToRun,
  24. stKnownRunProblem,
  25. stSuccessFullyRun,
  26. stSkippingGraphTest,
  27. stSkippingInteractiveTest,
  28. stSkippingKnownBug,
  29. stSkippingCompilerVersionTooLow,
  30. stSkippingCompilerVersionTooHigh,
  31. stSkippingOtherCpu,
  32. stSkippingOtherTarget,
  33. stskippingRunUnit,
  34. stskippingRunTest
  35. );
  36. Const
  37. FirstStatus = stFailedToCompile;
  38. LastStatus = stskippingRunTest;
  39. TestOK : Array[TTestStatus] of Boolean = (
  40. False, // stFailedToCompile,
  41. True, // stSuccessCompilationFailed,
  42. False, // stFailedCompilationsuccessful,
  43. True, // stSuccessfullyCompiled,
  44. False, // stFailedToRun,
  45. True, // stKnownRunProblem,
  46. True, // stSuccessFullyRun,
  47. False, // stSkippingGraphTest,
  48. False, // stSkippingInteractiveTest,
  49. False, // stSkippingKnownBug,
  50. False, // stSkippingCompilerVersionTooLow,
  51. False, // stSkippingCompilerVersionTooHigh,
  52. False, // stSkippingOtherCpu,
  53. False, // stSkippingOtherTarget,
  54. False, // stskippingRunUnit,
  55. False // stskippingRunTest
  56. );
  57. TestSkipped : Array[TTestStatus] of Boolean = (
  58. False, // stFailedToCompile,
  59. False, // stSuccessCompilationFailed,
  60. False, // stFailedCompilationsuccessful,
  61. False, // stSuccessfullyCompiled,
  62. False, // stFailedToRun,
  63. False, // stKnownRunProblem,
  64. False, // stSuccessFullyRun,
  65. True, // stSkippingGraphTest,
  66. True, // stSkippingInteractiveTest,
  67. True, // stSkippingKnownBug,
  68. True, // stSkippingCompilerVersionTooLow,
  69. True, // stSkippingCompilerVersionTooHigh,
  70. True, // stSkippingOtherCpu,
  71. True, // stSkippingOtherTarget,
  72. True, // stskippingRunUnit,
  73. True // stskippingRunTest
  74. );
  75. ExpectRun : Array[TTestStatus] of Boolean = (
  76. False, // stFailedToCompile,
  77. False, // stSuccessCompilationFailed,
  78. False, // stFailedCompilationsuccessful,
  79. True , // stSuccessfullyCompiled,
  80. False, // stFailedToRun,
  81. False, // stKnownRunProblem,
  82. False, // stSuccessFullyRun,
  83. False, // stSkippingGraphTest,
  84. False, // stSkippingInteractiveTest,
  85. False, // stSkippingKnownBug,
  86. False, // stSkippingCompilerVersionTooLow,
  87. False, // stSkippingCompilerVersionTooHigh,
  88. False, // stSkippingOtherCpu,
  89. False, // stSkippingOtherTarget,
  90. False, // stskippingRunUnit,
  91. False // stskippingRunTest
  92. );
  93. StatusText : Array[TTestStatus] of String = (
  94. failed_to_compile,
  95. success_compilation_failed,
  96. failed_compilation_successful ,
  97. successfully_compiled ,
  98. failed_to_run ,
  99. known_problem ,
  100. successfully_run ,
  101. skipping_graph_test ,
  102. skipping_interactive_test ,
  103. skipping_known_bug ,
  104. skipping_compiler_version_too_low,
  105. skipping_compiler_version_too_high,
  106. skipping_other_cpu ,
  107. skipping_other_target ,
  108. skipping_run_unit ,
  109. skipping_run_test
  110. );
  111. SQLField : Array[TTestStatus] of String = (
  112. 'TU_FAILEDTOCOMPILE',
  113. 'TU_SUCCESSFULLYFAILED',
  114. 'TU_FAILEDTOFAIL',
  115. 'TU_SUCCESFULLYCOMPILED',
  116. 'TU_FAILEDTORUN',
  117. 'TU_KNOWNPROBLEM',
  118. 'TU_SUCCESSFULLYRUN',
  119. 'TU_SKIPPEDGRAPHTEST',
  120. 'TU_SKIPPEDINTERACTIVETEST',
  121. 'TU_KNOWNBUG',
  122. 'TU_COMPILERVERIONTOOLOW',
  123. 'TU_COMPILERVERIONTOOHIGH',
  124. 'TU_OTHERCPU',
  125. 'TU_OTHERTARGET',
  126. 'TU_UNIT',
  127. 'TU_SKIPPINGRUNTEST'
  128. );
  129. Var
  130. StatusCount : Array[TTestStatus] of Integer;
  131. UnknownLines : integer;
  132. Procedure ExtractTestFileName(Var Line : string);
  133. Var I : integer;
  134. begin
  135. I:=Pos(' ',Line);
  136. If (I<>0) then
  137. Line:=Copy(Line,1,I-1);
  138. end;
  139. Function Analyse(Var Line : string; Var Status : TTestStatus) : Boolean;
  140. Var
  141. TS : TTestStatus;
  142. begin
  143. Result:=False;
  144. For TS:=FirstStatus to LastStatus do
  145. begin
  146. Result:=Pos(StatusText[TS],Line)=1;
  147. If Result then
  148. begin
  149. Status:=TS;
  150. Delete(Line,1,Length(StatusText[TS]));
  151. ExtractTestFileName(Line);
  152. Break;
  153. end;
  154. end;
  155. end;
  156. Type
  157. TConfigOpt = (
  158. coDatabaseName,
  159. soHost,
  160. coUserName,
  161. coPassword,
  162. coLogFile,
  163. coOS,
  164. coCPU,
  165. coVersion,
  166. coDate,
  167. coSubmitter,
  168. coMachine,
  169. coComment,
  170. coTestSrcDir,
  171. coVerbose
  172. );
  173. Const
  174. ConfigStrings : Array [TConfigOpt] of string = (
  175. 'databasename',
  176. 'host',
  177. 'username',
  178. 'password',
  179. 'logfile',
  180. 'os',
  181. 'cpu',
  182. 'version',
  183. 'date',
  184. 'submitter',
  185. 'machine',
  186. 'comment',
  187. 'testsrcdir',
  188. 'verbose'
  189. );
  190. ConfigOpts : Array[TConfigOpt] of char
  191. = ('d','h','u','p','l','o','c','v','t','s','m','C','S','V');
  192. Var
  193. TestOS,
  194. TestCPU,
  195. TestVersion,
  196. DatabaseName,
  197. HostName,
  198. UserName,
  199. Password,
  200. LogFileName,
  201. Submitter,
  202. Machine,
  203. Comment : String;
  204. TestDate : TDateTime;
  205. Procedure SetOpt (O : TConfigOpt; Value : string);
  206. var
  207. year,month,day,min,hour : word;
  208. begin
  209. Case O of
  210. coDatabaseName : DatabaseName:=Value;
  211. soHost : HostName:=Value;
  212. coUserName : UserName:=Value;
  213. coPassword : Password:=Value;
  214. coLogFile : LogFileName:=Value;
  215. coOS : TestOS:=Value;
  216. coCPU : TestCPU:=Value;
  217. coVersion : TestVersion:=Value;
  218. coDate :
  219. begin
  220. { Formated like YYYYMMDDhhmm }
  221. if Length(value)=12 then
  222. begin
  223. year:=StrToInt(Copy(value,1,4));
  224. month:=StrToInt(Copy(value,5,2));
  225. day:=StrToInt(Copy(Value,7,2));
  226. hour:=StrToInt(Copy(Value,9,2));
  227. min:=StrToInt(Copy(Value,11,2));
  228. TestDate:=EncodeDate(year,month,day)+EncodeTime(hour,min,0,0);
  229. end
  230. else
  231. Verbose(V_Error,'Error in date format, use YYYYMMDDhhmm');
  232. end;
  233. coSubmitter : Submitter:=Value;
  234. coMachine : Machine:=Value;
  235. coComment : Comment:=Value;
  236. coVerbose : DoVerbose:=true;
  237. coTestSrcDir :
  238. begin
  239. TestSrcDir:=Value;
  240. if (TestSrcDir<>'') and (TestSrcDir[length(TestSrcDir)]<>'/') then
  241. TestSrcDir:=TestSrcDir+'/';
  242. end;
  243. end;
  244. end;
  245. Function ProcessOption(S: String) : Boolean;
  246. Var
  247. N : String;
  248. I : Integer;
  249. co : TConfigOpt;
  250. begin
  251. Verbose(V_DEBUG,'Processing option: '+S);
  252. I:=Pos('=',S);
  253. Result:=(I<>0);
  254. If Result then
  255. begin
  256. N:=Copy(S,1,I-1);
  257. Delete(S,1,I);
  258. For co:=low(TConfigOpt) to high(TConfigOpt) do
  259. begin
  260. Result:=CompareText(ConfigStrings[co],N)=0;
  261. If Result then
  262. Break;
  263. end;
  264. end;
  265. If Result then
  266. SetOpt(co,S)
  267. else
  268. Verbose(V_ERROR,'Unknown option : '+n+S);
  269. end;
  270. Procedure ProcessConfigfile(FN : String);
  271. Var
  272. F : Text;
  273. S : String;
  274. I : Integer;
  275. begin
  276. If Not FileExists(FN) Then
  277. Exit;
  278. Verbose(V_DEBUG,'Parsing config file: '+FN);
  279. Assign(F,FN);
  280. {$i-}
  281. Reset(F);
  282. If IOResult<>0 then
  283. Exit;
  284. {$I+}
  285. While not(EOF(F)) do
  286. begin
  287. ReadLn(F,S);
  288. S:=trim(S);
  289. I:=Pos('#',S);
  290. If I<>0 then
  291. S:=Copy(S,1,I-1);
  292. If (S<>'') then
  293. ProcessOption(S);
  294. end;
  295. Close(F);
  296. end;
  297. Procedure ProcessCommandLine;
  298. Var
  299. I : Integer;
  300. O : String;
  301. c,co : TConfigOpt;
  302. Found : Boolean;
  303. begin
  304. I:=1;
  305. While I<=ParamCount do
  306. begin
  307. O:=Paramstr(I);
  308. Found:=Length(O)=2;
  309. If Found then
  310. For co:=low(TConfigOpt) to high(TConfigOpt) do
  311. begin
  312. Found:=(O[2]=ConfigOpts[co]);
  313. If Found then
  314. begin
  315. c:=co;
  316. Break;
  317. end;
  318. end;
  319. If Not Found then
  320. Verbose(V_ERROR,'Illegal command-line option : '+O)
  321. else
  322. begin
  323. Found:=(I<ParamCount);
  324. If Not found then
  325. Verbose(V_ERROR,'Option requires argument : '+O)
  326. else
  327. begin
  328. inc(I);
  329. O:=Paramstr(I);
  330. SetOpt(c,o);
  331. end;
  332. end;
  333. Inc(I);
  334. end;
  335. end;
  336. Var
  337. TestCPUID : Integer;
  338. TestOSID : Integer;
  339. TestVersionID : Integer;
  340. TestRunID : Integer;
  341. Procedure GetIDs;
  342. begin
  343. TestCPUID := GetCPUId(TestCPU);
  344. If TestCPUID=-1 then
  345. Verbose(V_Error,'NO ID for CPU "'+TestCPU+'" found.');
  346. TestOSID := GetOSID(TestOS);
  347. If TestOSID=-1 then
  348. Verbose(V_Error,'NO ID for OS "'+TestOS+'" found.');
  349. TestVersionID := GetVersionID(TestVersion);
  350. If TestVersionID=-1 then
  351. Verbose(V_Error,'NO ID for version "'+TestVersion+'" found.');
  352. If (Round(TestDate)=0) then
  353. Testdate:=Now;
  354. TestRunID:=GetRunID(TestOSID,TestCPUID,TestVersionID,TestDate);
  355. If (TestRunID=-1) then
  356. begin
  357. TestRunID:=AddRun(TestOSID,TestCPUID,TestVersionID,TestDate);
  358. If TestRUnID=-1 then
  359. Verbose(V_Error,'Could not insert new testrun record!');
  360. end
  361. else
  362. CleanTestRun(TestRunID);
  363. end;
  364. Function GetLog(FN : String) : String;
  365. begin
  366. FN:=ChangeFileExt(FN,'.elg');
  367. If FileExists(FN) then
  368. Result:=GetFileContents(FN)
  369. else
  370. Result:='';
  371. end;
  372. Procedure Processfile (FN: String);
  373. var
  374. logfile : text;
  375. line : string;
  376. TS : TTestStatus;
  377. ID : integer;
  378. Testlog : string;
  379. begin
  380. Assign(logfile,FN);
  381. {$i-}
  382. reset(logfile);
  383. if ioresult<>0 then
  384. Verbose(V_Error,'Unable to open log file'+logfilename);
  385. {$i+}
  386. while not eof(logfile) do
  387. begin
  388. readln(logfile,line);
  389. If analyse(line,TS) then
  390. begin
  391. Verbose(V_NORMAL,'Analysing result for test '+Line);
  392. Inc(StatusCount[TS]);
  393. If Not ExpectRun[TS] then
  394. begin
  395. ID:=RequireTestID(Line);
  396. If (ID<>-1) then
  397. begin
  398. If Not (TestOK[TS] or TestSkipped[TS]) then
  399. TestLog:=GetLog(Line)
  400. else
  401. TestLog:='';
  402. AddTestResult(ID,TestRunID,Ord(TS),TestOK[TS],TestSkipped[TS],TestLog);
  403. end;
  404. end
  405. end
  406. else
  407. Inc(UnknownLines);
  408. end;
  409. close(logfile);
  410. end;
  411. procedure UpdateTestRun;
  412. var
  413. i : TTestStatus;
  414. qry : string;
  415. res : TQueryResult;
  416. begin
  417. qry:='UPDATE TESTRUN SET ';
  418. for i:=low(TTestStatus) to high(TTestStatus) do
  419. qry:=qry+format('%s=%d, ',[SQLField[i],StatusCount[i]]);
  420. qry:=qry+format('TU_SUBMITTER="%s", TU_MACHINE="%s", TU_COMMENT="%s", TU_DATE="%s"',[Submitter,Machine,Comment,SqlDate(TestDate)]);
  421. qry:=qry+' WHERE TU_ID='+format('%d',[TestRunID]);
  422. RunQuery(Qry,res)
  423. end;
  424. begin
  425. ProcessConfigFile('dbdigest.cfg');
  426. ProcessCommandLine;
  427. If LogFileName<>'' then
  428. begin
  429. ConnectToDatabase(DatabaseName,HostName,UserName,Password);
  430. GetIDs;
  431. ProcessFile(LogFileName);
  432. UpdateTestRun;
  433. end
  434. else
  435. Verbose(V_ERROR,'Missing log file name');
  436. end.