dbdigest.pp 11 KB

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