{ $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:=(I0 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 }