mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-26 21:03:59 +02:00
519 lines
11 KiB
ObjectPascal
519 lines
11 KiB
ObjectPascal
{
|
|
$Id$
|
|
This file is part of the Free Pascal test suite.
|
|
Copyright (c) 2002 by the Free Pascal development team.
|
|
|
|
This program generates a digest
|
|
of the last tests run.
|
|
|
|
See the file COPYING.FPC, included in this distribution,
|
|
for details about the copyright.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
**********************************************************************}
|
|
|
|
{$mode objfpc}
|
|
{$h+}
|
|
|
|
program digest;
|
|
|
|
uses
|
|
sysutils,teststr,testu,dbtests;
|
|
|
|
|
|
Type
|
|
TTestStatus = (
|
|
stFailedToCompile,
|
|
stSuccessCompilationFailed,
|
|
stFailedCompilationsuccessful,
|
|
stSuccessfullyCompiled,
|
|
stFailedToRun,
|
|
stKnownRunProblem,
|
|
stSuccessFullyRun,
|
|
stSkippingGraphTest,
|
|
stSkippingInteractiveTest,
|
|
stSkippingKnownBug,
|
|
stSkippingCompilerVersionTooLow,
|
|
stSkippingCompilerVersionTooHigh,
|
|
stSkippingOtherCpu,
|
|
stSkippingOtherTarget,
|
|
stskippingRunUnit,
|
|
stskippingRunTest
|
|
);
|
|
|
|
|
|
Const
|
|
FirstStatus = stFailedToCompile;
|
|
LastStatus = stskippingRunTest;
|
|
|
|
TestOK : Array[TTestStatus] of Boolean = (
|
|
False, // stFailedToCompile,
|
|
True, // stSuccessCompilationFailed,
|
|
False, // stFailedCompilationsuccessful,
|
|
True, // stSuccessfullyCompiled,
|
|
False, // stFailedToRun,
|
|
True, // stKnownRunProblem,
|
|
True, // stSuccessFullyRun,
|
|
False, // stSkippingGraphTest,
|
|
False, // stSkippingInteractiveTest,
|
|
False, // stSkippingKnownBug,
|
|
False, // stSkippingCompilerVersionTooLow,
|
|
False, // stSkippingCompilerVersionTooHigh,
|
|
False, // stSkippingOtherCpu,
|
|
False, // stSkippingOtherTarget,
|
|
False, // stskippingRunUnit,
|
|
False // stskippingRunTest
|
|
);
|
|
|
|
TestSkipped : Array[TTestStatus] of Boolean = (
|
|
False, // stFailedToCompile,
|
|
False, // stSuccessCompilationFailed,
|
|
False, // stFailedCompilationsuccessful,
|
|
False, // stSuccessfullyCompiled,
|
|
False, // stFailedToRun,
|
|
False, // stKnownRunProblem,
|
|
False, // stSuccessFullyRun,
|
|
True, // stSkippingGraphTest,
|
|
True, // stSkippingInteractiveTest,
|
|
True, // stSkippingKnownBug,
|
|
True, // stSkippingCompilerVersionTooLow,
|
|
True, // stSkippingCompilerVersionTooHigh,
|
|
True, // stSkippingOtherCpu,
|
|
True, // stSkippingOtherTarget,
|
|
True, // stskippingRunUnit,
|
|
True // stskippingRunTest
|
|
);
|
|
|
|
ExpectRun : Array[TTestStatus] of Boolean = (
|
|
False, // stFailedToCompile,
|
|
False, // stSuccessCompilationFailed,
|
|
False, // stFailedCompilationsuccessful,
|
|
True , // stSuccessfullyCompiled,
|
|
False, // stFailedToRun,
|
|
False, // stKnownRunProblem,
|
|
False, // stSuccessFullyRun,
|
|
False, // stSkippingGraphTest,
|
|
False, // stSkippingInteractiveTest,
|
|
False, // stSkippingKnownBug,
|
|
False, // stSkippingCompilerVersionTooLow,
|
|
False, // stSkippingCompilerVersionTooHigh,
|
|
False, // stSkippingOtherCpu,
|
|
False, // stSkippingOtherTarget,
|
|
False, // stskippingRunUnit,
|
|
False // stskippingRunTest
|
|
);
|
|
|
|
StatusText : Array[TTestStatus] of String = (
|
|
failed_to_compile,
|
|
success_compilation_failed,
|
|
failed_compilation_successful ,
|
|
successfully_compiled ,
|
|
failed_to_run ,
|
|
known_problem ,
|
|
successfully_run ,
|
|
skipping_graph_test ,
|
|
skipping_interactive_test ,
|
|
skipping_known_bug ,
|
|
skipping_compiler_version_too_low,
|
|
skipping_compiler_version_too_high,
|
|
skipping_other_cpu ,
|
|
skipping_other_target ,
|
|
skipping_run_unit ,
|
|
skipping_run_test
|
|
);
|
|
|
|
SQLField : Array[TTestStatus] of String = (
|
|
'TU_FAILEDTOCOMPILE',
|
|
'TU_SUCCESSFULLYFAILED',
|
|
'TU_FAILEDTOFAIL',
|
|
'TU_SUCCESFULLYCOMPILED',
|
|
'TU_FAILEDTORUN',
|
|
'TU_KNOWNPROBLEM',
|
|
'TU_SUCCESSFULLYRUN',
|
|
'TU_SKIPPEDGRAPHTEST',
|
|
'TU_SKIPPEDINTERACTIVETEST',
|
|
'TU_KNOWNBUG',
|
|
'TU_COMPILERVERIONTOOLOW',
|
|
'TU_COMPILERVERIONTOOHIGH',
|
|
'TU_OTHERCPU',
|
|
'TU_OTHERTARGET',
|
|
'TU_UNIT',
|
|
'TU_SKIPPINGRUNTEST'
|
|
);
|
|
|
|
|
|
Var
|
|
StatusCount : Array[TTestStatus] of Integer;
|
|
UnknownLines,
|
|
unexpected_run : Integer;
|
|
next_should_be_run : boolean;
|
|
|
|
var
|
|
prevline : string;
|
|
|
|
Procedure ExtractTestFileName(Var Line : string);
|
|
|
|
Var I : integer;
|
|
|
|
begin
|
|
I:=Pos(' ',Line);
|
|
If (I<>0) then
|
|
Line:=Copy(Line,1,I-1);
|
|
end;
|
|
|
|
Function Analyse(Var Line : string; Var Status : TTestStatus) : Boolean;
|
|
|
|
Var
|
|
TS : TTestStatus;
|
|
Found : Boolean;
|
|
|
|
begin
|
|
Result:=False;
|
|
For TS:=FirstStatus to LastStatus do
|
|
begin
|
|
Result:=Pos(StatusText[TS],Line)=1;
|
|
If Result then
|
|
begin
|
|
Status:=TS;
|
|
Delete(Line,1,Length(StatusText[TS]));
|
|
ExtractTestFileName(Line);
|
|
Break;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
Type
|
|
|
|
TConfigOpt = (
|
|
coDatabaseName,
|
|
soHost,
|
|
coUserName,
|
|
coPassword,
|
|
coLogFile,
|
|
coOS,
|
|
coCPU,
|
|
coVersion,
|
|
coDate,
|
|
coSubmitter,
|
|
coMachine,
|
|
coComment
|
|
);
|
|
|
|
Const
|
|
|
|
ConfigStrings : Array [TConfigOpt] of string = (
|
|
'databasename',
|
|
'host',
|
|
'username',
|
|
'password',
|
|
'logfile',
|
|
'os',
|
|
'cpu',
|
|
'version',
|
|
'date',
|
|
'submitter',
|
|
'machine',
|
|
'comment'
|
|
);
|
|
|
|
ConfigOpts : Array[TConfigOpt] of char
|
|
= ('d','h','u','p','l','o','c','v','t','s','m','C');
|
|
|
|
Var
|
|
TestOS,
|
|
TestCPU,
|
|
TestVersion,
|
|
DatabaseName,
|
|
HostName,
|
|
UserName,
|
|
Password,
|
|
LogFileName,
|
|
Submitter,
|
|
Machine,
|
|
Comment : String;
|
|
TestDate : TDateTime;
|
|
|
|
Procedure SetOpt (O : TConfigOpt; Value : string);
|
|
|
|
begin
|
|
Case O of
|
|
coDatabaseName : DatabaseName:=Value;
|
|
soHost : HostName:=Value;
|
|
coUserName : UserName:=Value;
|
|
coPassword : Password:=Value;
|
|
coLogFile : LogFileName:=Value;
|
|
coOS : TestOS:=Value;
|
|
coCPU : TestCPU:=Value;
|
|
coVersion : TestVersion:=Value;
|
|
coDate : TestDate:=StrToDate(Value);
|
|
coSubmitter : Submitter:=Value;
|
|
coMachine : Machine:=Value;
|
|
coComment : Comment:=Value;
|
|
end;
|
|
end;
|
|
|
|
Function ProcessOption(S: String) : Boolean;
|
|
|
|
Var
|
|
N : String;
|
|
I : Integer;
|
|
Found : Boolean;
|
|
co,o : TConfigOpt;
|
|
|
|
begin
|
|
Verbose(V_DEBUG,'Processing option: '+S);
|
|
I:=Pos('=',S);
|
|
Result:=(I<>0);
|
|
If Result then
|
|
begin
|
|
N:=Copy(S,1,I-1);
|
|
Delete(S,1,I);
|
|
For co:=low(TConfigOpt) to high(TConfigOpt) do
|
|
begin
|
|
Result:=CompareText(ConfigStrings[co],N)=0;
|
|
If Result then
|
|
begin
|
|
o:=co;
|
|
Break;
|
|
end;
|
|
end;
|
|
end;
|
|
If Result then
|
|
SetOpt(co,S)
|
|
else
|
|
Verbose(V_ERROR,'Unknown option : '+n+S);
|
|
end;
|
|
|
|
Procedure ProcessConfigfile(FN : String);
|
|
|
|
Var
|
|
F : Text;
|
|
S : String;
|
|
I : Integer;
|
|
|
|
begin
|
|
If Not FileExists(FN) Then
|
|
Exit;
|
|
Verbose(V_DEBUG,'Parsing config file: '+FN);
|
|
Assign(F,FN);
|
|
{$i-}
|
|
Reset(F);
|
|
If IOResult<>0 then
|
|
Exit;
|
|
{$I+}
|
|
While not(EOF(F)) do
|
|
begin
|
|
ReadLn(F,S);
|
|
S:=trim(S);
|
|
I:=Pos('#',S);
|
|
If I<>0 then
|
|
S:=Copy(S,1,I-1);
|
|
If (S<>'') then
|
|
ProcessOption(S);
|
|
end;
|
|
Close(F);
|
|
end;
|
|
|
|
Procedure ProcessCommandLine;
|
|
|
|
Var
|
|
I : Integer;
|
|
O,V : String;
|
|
c,co : TConfigOpt;
|
|
Found : Boolean;
|
|
|
|
begin
|
|
I:=1;
|
|
While I<=ParamCount do
|
|
begin
|
|
O:=Paramstr(I);
|
|
Found:=Length(O)=2;
|
|
If Found then
|
|
For co:=low(TConfigOpt) to high(TConfigOpt) do
|
|
begin
|
|
Found:=(O[2]=ConfigOpts[co]);
|
|
If Found then
|
|
begin
|
|
c:=co;
|
|
Break;
|
|
end;
|
|
end;
|
|
If Not Found then
|
|
Verbose(V_ERROR,'Illegal command-line option : '+O)
|
|
else
|
|
begin
|
|
Found:=(I<ParamCount);
|
|
If Not found then
|
|
Verbose(V_ERROR,'Option requires argument : '+O)
|
|
else
|
|
begin
|
|
inc(I);
|
|
O:=Paramstr(I);
|
|
SetOpt(c,o);
|
|
end;
|
|
end;
|
|
Inc(I);
|
|
end;
|
|
end;
|
|
|
|
Var
|
|
TestCPUID : Integer;
|
|
TestOSID : Integer;
|
|
TestVersionID : Integer;
|
|
TestRunID : Integer;
|
|
|
|
Procedure GetIDs;
|
|
|
|
begin
|
|
TestCPUID := GetCPUId(TestCPU);
|
|
If TestCPUID=-1 then
|
|
Verbose(V_Error,'NO ID for CPU "'+TestCPU+'" found.');
|
|
TestOSID := GetOSID(TestOS);
|
|
If TestOSID=-1 then
|
|
Verbose(V_Error,'NO ID for OS "'+TestOS+'" found.');
|
|
TestVersionID := GetVersionID(TestVersion);
|
|
If TestVersionID=-1 then
|
|
Verbose(V_Error,'NO ID for version "'+TestVersion+'" found.');
|
|
If (Round(TestDate)=0) then
|
|
Testdate:=Now;
|
|
TestRunID:=GetRunID(TestOSID,TestCPUID,TestVersionID,TestDate);
|
|
If (TestRunID=-1) then
|
|
begin
|
|
TestRunID:=AddRun(TestOSID,TestCPUID,TestVersionID,TestDate);
|
|
If TestRUnID=-1 then
|
|
Verbose(V_Error,'Could not insert new testrun record!');
|
|
end
|
|
else
|
|
CleanTestRun(TestRunID);
|
|
end;
|
|
|
|
Function GetLog(FN : String) : String;
|
|
|
|
begin
|
|
FN:=ChangeFileExt(FN,'.elg');
|
|
If FileExists(FN) then
|
|
Result:=GetFileContents(FN)
|
|
else
|
|
Result:='';
|
|
end;
|
|
|
|
Procedure Processfile (FN: String);
|
|
|
|
var
|
|
logfile : text;
|
|
line : string;
|
|
TS : TTestStatus;
|
|
ID : integer;
|
|
Testlog : string;
|
|
|
|
begin
|
|
Assign(logfile,FN);
|
|
{$i-}
|
|
reset(logfile);
|
|
if ioresult<>0 then
|
|
Verbose(V_Error,'Unable to open log file'+logfilename);
|
|
{$i+}
|
|
while not eof(logfile) do
|
|
begin
|
|
readln(logfile,line);
|
|
If analyse(line,TS) then
|
|
begin
|
|
Verbose(V_NORMAL,'Analysing result for test '+Line);
|
|
Inc(StatusCount[TS]);
|
|
If Not ExpectRun[TS] then
|
|
begin
|
|
ID:=RequireTestID(Line);
|
|
If (ID<>-1) then
|
|
begin
|
|
If Not (TestOK[TS] or TestSkipped[TS]) then
|
|
TestLog:=GetLog(Line)
|
|
else
|
|
TestLog:='';
|
|
AddTestResult(ID,TestRunID,Ord(TS),TestOK[TS],TestSkipped[TS],TestLog);
|
|
end;
|
|
end
|
|
end
|
|
else
|
|
Inc(UnknownLines);
|
|
end;
|
|
close(logfile);
|
|
end;
|
|
|
|
procedure UpdateTestRun;
|
|
|
|
var
|
|
i : TTestStatus;
|
|
qry : string;
|
|
res : TQueryResult;
|
|
|
|
begin
|
|
qry:='UPDATE TESTRUN SET ';
|
|
for i:=low(TTestStatus) to high(TTestStatus) do
|
|
qry:=qry+format('%s=%d, ',[SQLField[i],StatusCount[i]]);
|
|
qry:=qry+format('TU_SUBMITTER="%s", TU_MACHINE="%s", TU_COMMENT="%s"',[Submitter,Machine,Comment]);
|
|
qry:=qry+' WHERE TU_ID='+format('%d',[TestRunID]);
|
|
RunQuery(Qry,res)
|
|
end;
|
|
|
|
|
|
begin
|
|
ProcessConfigFile('dbdigest.cfg');
|
|
ProcessCommandLine;
|
|
If LogFileName<>'' then
|
|
begin
|
|
ConnectToDatabase(DatabaseName,HostName,UserName,Password);
|
|
GetIDs;
|
|
ProcessFile(LogFileName);
|
|
UpdateTestRun;
|
|
end
|
|
else
|
|
Verbose(V_ERROR,'Missing log file name');
|
|
end.
|
|
|
|
{
|
|
$Log$
|
|
Revision 1.11 2003-10-17 08:08:07 florian
|
|
* cosmetic fix in console output
|
|
|
|
Revision 1.10 2003/10/15 21:45:50 florian
|
|
+ added submitter, machine and comment field to sql version
|
|
|
|
Revision 1.9 2003/10/15 19:39:42 florian
|
|
* exact result counts are inserted into the table
|
|
|
|
Revision 1.8 2003/10/13 14:19:02 peter
|
|
* digest updated for max version limit
|
|
|
|
Revision 1.7 2003/10/06 16:53:04 fpc
|
|
* allow digest programs on commandline
|
|
|
|
Revision 1.6 2003/10/04 21:30:21 florian
|
|
+ added time to timestamp so multiple runs per day can be done
|
|
|
|
Revision 1.5 2003/10/03 22:51:02 michael
|
|
+ Changed database structure after suggestion of florian
|
|
|
|
Revision 1.4 2002/12/24 21:47:49 peter
|
|
* NeedTarget, SkipTarget, SkipCPU added
|
|
* Retrieve compiler info in a single call for 1.1 compiler
|
|
|
|
Revision 1.3 2002/12/21 15:39:11 michael
|
|
* Some verbosity changes
|
|
|
|
Revision 1.2 2002/12/21 15:31:16 michael
|
|
+ Added support for compiler version
|
|
|
|
Revision 1.1 2002/12/17 15:04:32 michael
|
|
+ Added dbdigest to store results in a database
|
|
|
|
Revision 1.2 2002/11/18 16:42:43 pierre
|
|
+ KNOWNRUNERROR added
|
|
|
|
Revision 1.1 2002/11/13 15:26:24 pierre
|
|
+ digest program added
|
|
|
|
}
|