ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/public/ibx/trunk/testsuite/IBXTestBase.pas
Revision: 402
Committed: Mon Aug 1 10:07:24 2022 UTC (2 years, 1 month ago) by tony
Content type: text/x-pascal
File size: 13324 byte(s)
Log Message:
IBX Release 2.5.0

File Contents

# User Rev Content
1 tony 323 (*
2     * IBX Test suite. This program is used to test the IBX non-visual
3     * components and provides a semi-automated pass/fail check for each test.
4     *
5     * The contents of this file are subject to the Initial Developer's
6     * Public License Version 1.0 (the "License"); you may not use this
7     * file except in compliance with the License. You may obtain a copy
8     * of the License here:
9     *
10     * http://www.firebirdsql.org/index.php?op=doc&id=idpl
11     *
12     * Software distributed under the License is distributed on an "AS
13     * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
14     * implied. See the License for the specific language governing rights
15     * and limitations under the License.
16     *
17     * The Initial Developer of the Original Code is Tony Whyman.
18     *
19     * The Original Code is (C) 2021 Tony Whyman, MWA Software
20     * (http://www.mwasoftware.co.uk).
21     *
22     * All Rights Reserved.
23     *
24     * Contributor(s): ______________________________________.
25     *
26     *)
27 tony 315 unit IBXTestBase;
28    
29     {$mode objfpc}{$H+}
30    
31     interface
32    
33     uses
34     Classes, SysUtils, TestApplication, CustApp, DB, IB, IBCustomDataSet, IBDatabase, IBQuery,
35     ibxscript, IBDataOutput, IBSQL;
36    
37     type
38    
39     { TIBXTestBase }
40    
41     TIBXTestBase = class(TTestBase)
42     private
43     FIBDatabase: TIBDatabase;
44     FIBTransaction: TIBTransaction;
45     FIBQuery: TIBQuery;
46     FIBXScript: TIBXScript;
47     FInitialising: boolean;
48     FScriptFile: AnsiString;
49     function GetRoleName: AnsiString;
50     function GetScriptFile: AnsiString;
51     procedure HandleCreateDatebase(Sender: TObject);
52     procedure HandleDBFileName(Sender: TObject; var DatabaseFileName: string);
53     procedure LogHandler(Sender: TObject; Msg: string);
54     procedure ErrorLogHandler(Sender: TObject; Msg: string);
55     protected
56     procedure ClientLibraryPathChanged; override;
57     procedure CreateObjects(Application: TTestApplication); override;
58     function GetFullTestID: string;
59     function GetOutFile: string;
60     function GetSSBackupFile: string;
61     procedure InitialiseDatabase(aDatabase: TIBDatabase); virtual;
62 tony 402 procedure ListFields(aDataset: TDataSet);
63 tony 315 procedure PrintDataSet(aDataSet: TDataSet);
64     procedure PrintDataSetRow(aDataSet: TDataSet); overload;
65     procedure PrintDataSetRow(aField: TField); overload;
66     procedure PrintAffectedRows(query: TIBCustomDataSet); overload;
67     procedure PrintAffectedRows(query: TIBSQL); overload;
68     procedure ReadOnlyTransaction;
69     procedure ReadWriteTransaction;
70     procedure RunScript(aDatabase: TIBDatabase; aFileName: string);
71     procedure ShowStrings(aCaption: string; List: TStrings);
72     procedure WriteStrings(List: TStrings; limit: integer=0);
73     procedure ExecuteSQL(SQL: string);
74     procedure ShowFBVersion(attachment: IAttachment);
75     procedure ShowBoolValue(aValue: integer; WhenTrue, WhenFalse: string);
76     procedure ProcessResults; override;
77     public
78     destructor Destroy; override;
79 tony 402 procedure CompareFiles(F1, F2: string);
80 tony 315 property IBDatabase: TIBDatabase read FIBDatabase;
81     property IBTransaction: TIBTransaction read FIBTransaction;
82     property IBQuery: TIBQuery read FIBQuery;
83     property RoleName: AnsiString read GetRoleName;
84     property IBXScriptObj: TIBXScript read FIBXScript;
85     end;
86    
87     implementation
88    
89     uses Process, IBUtils;
90    
91     const
92     sqlScriptTemplate = 'resources/Test%s.sql';
93     sqlCustomScriptTemplate = 'resources/Test%s.%d.sql';
94     outFileTemplate = 'Test%s.out';
95    
96     { TIBXTestBase }
97    
98     procedure TIBXTestBase.HandleCreateDatebase(Sender: TObject);
99     begin
100     if not FInitialising then
101     begin
102     FInitialising := true;
103     try
104     InitialiseDatabase(IBDatabase);
105     finally
106     FInitialising := false;
107     end;
108     end;
109     end;
110    
111     function TIBXTestBase.GetRoleName: AnsiString;
112     begin
113     if IBDatabase.Connected then
114     Result := IBDatabase.Attachment.OpenCursorAtStart(IBTransaction.TransactionIntf,
115     'Select CURRENT_ROLE From RDB$Database',[])[0].AsString
116     else
117     Result := '';
118     end;
119    
120     function TIBXTestBase.GetScriptFile: AnsiString;
121     begin
122     FScriptFile := '';
123     if IBDatabase.Attachment <> nil then
124     FScriptFile := Format(sqlCustomScriptTemplate,[GetFullTestID,IBDatabase.Attachment.GetODSMajorVersion]);
125     if not FileExists(FScriptFile) then
126     FScriptFile := Format(sqlScriptTemplate,[GetFullTestID]);
127     Result := FScriptFile;
128     end;
129    
130     procedure TIBXTestBase.HandleDBFileName(Sender: TObject;
131     var DatabaseFileName: string);
132     begin
133     DatabaseFileName := IBDatabase.DatabaseName;
134     end;
135    
136     procedure TIBXTestBase.LogHandler(Sender: TObject; Msg: string);
137     begin
138     writeln(OutFile,Msg);
139     end;
140    
141     procedure TIBXTestBase.ErrorLogHandler(Sender: TObject; Msg: string);
142     begin
143     writeln(OutFile,Msg);
144     end;
145    
146     procedure TIBXTestBase.ClientLibraryPathChanged;
147     begin
148     inherited ClientLibraryPathChanged;
149     FIBDatabase.FirebirdLibraryPathName := Owner.ClientLibraryPath;
150     end;
151    
152     procedure TIBXTestBase.CreateObjects(Application: TTestApplication);
153     begin
154     inherited CreateObjects(Application);
155     { In console Mode the application should own the database
156     - ensures centralised exception handling }
157     FIBDatabase := TIBDatabase.Create(Application);
158     FIBDatabase.FirebirdLibraryPathName := Owner.ClientLibraryPath;
159     FIBDatabase.LoginPrompt := false;
160     FIBDatabase.Params.Add('user_name=' + Owner.GetUserName);
161     FIBDatabase.Params.Add('password=' + Owner.GetPassword);
162     FIBDatabase.Params.Add('lc_ctype=UTF8');
163     FIBDatabase.OnCreateDatabase := @HandleCreateDatebase;
164     FIBDatabase.Name := 'Test_Database_' + GetTestID;
165     FIBTransaction := TIBTransaction.Create(Application);
166     FIBTransaction.DefaultDatabase := FIBDatabase;
167     FIBDatabase.DefaultTransaction := FIBTransaction;
168     FIBTransaction.Name := 'Test_Transaction_' + GetTestID;
169     FIBQuery := TIBQuery.Create(Application);
170     FIBQuery.Database := FIBDatabase;
171     FIBXScript := TIBXScript.Create(Application);
172     FIBXScript.Database := FIBDatabase;
173     FIBXScript.Transaction := FIBTransaction;
174     FIBXScript.OnOutputLog := @LogHandler;
175     FIBXScript.OnErrorLog := @ErrorLogHandler;
176     FIBXScript.DataOutputFormatter := TIBInsertStmtsOut.Create(Application);
177     FIBXScript.OnCreateDatabase := @HandleDBFileName;
178     FIBXScript.IgnoreCreateDatabase := FALSE;
179     end;
180    
181     function TIBXTestBase.GetFullTestID: string;
182     begin
183     Result := GetTestID;
184     if Length(Result) = 1 then
185     Result := '0' + Result;
186     end;
187    
188     function TIBXTestBase.GetOutFile: string;
189     begin
190     Result := Format(outFileTemplate,[GetFullTestID]);
191     end;
192    
193     function TIBXTestBase.GetSSBackupFile: string;
194     begin
195     Result := ChangeFileExt(Owner.GetBackupFileName,'.fbk');
196     end;
197    
198     procedure TIBXTestBase.InitialiseDatabase(aDatabase: TIBDatabase);
199     var aFileName: string;
200     {$IFDEF WINDOWS}
201     F: text;
202     line: AnsiString;
203     {$ENDIF}
204     begin
205     aFileName := GetScriptFile;
206     if FileExists(aFileName) then
207     begin
208     writeln(OutFile,'Creating Database from ' + aFileName);
209     writeln(OutFile);
210     {$IFDEF WINDOWS}
211     assignfile(F,aFileName);
212     try
213     Reset(F);
214     readln(F,line);
215     close(F);
216     if Pos('link ',Line) = 1 then
217     aFileName := ExtractFilePath(aFileName) + system.copy(Line,6,Length(Line)-5);
218     except
219     //do nothing
220     end;
221     {$ENDIF}
222     RunScript(aDatabase,aFileName);
223     end;
224     end;
225    
226 tony 402 procedure TIBXTestBase.ListFields(aDataset: TDataSet);
227     var i: integer;
228     begin
229     writeln(OutFile,'Field Names for ',aDataSet.Name);
230     for i := 0 to aDataSet.Fields.Count - 1 do
231     writeln(OutFile,aDataSet.Fields[i].FieldName);
232     writeln(OutFile);
233     end;
234    
235 tony 315 procedure TIBXTestBase.PrintDataSet(aDataSet: TDataSet);
236     var rowno: integer;
237     begin
238     if aDataSet.Name <> '' then
239     writeln(OutFile,'Print Dataset for ',aDataSet.Name);
240     aDataSet.First;
241     rowno := 1;
242     if aDataSet.EOF then
243     writeln(OutFile,'Dataset Empty')
244     else
245     while not aDataSet.EOF do
246     begin
247 tony 319 CheckSynchronize(100);
248 tony 315 writeln(OutFile,'Row No = ',rowno);
249     PrintDataSetRow(aDataset);
250     aDataSet.Next;
251     Inc(rowno);
252     writeln(OutFile);
253     end;
254     writeln(Outfile,'Rows printed = ',IntToStr(rowno-1));
255     writeln(Outfile);
256     end;
257    
258     procedure TIBXTestBase.PrintDataSetRow(aDataSet: TDataSet);
259     var i: integer;
260     begin
261     for i := 0 to aDataSet.FieldCount - 1 do
262     PrintDataSetRow(aDataSet.Fields[i]);
263     end;
264    
265     procedure TIBXTestBase.PrintDataSetRow(aField: TField);
266     var s: AnsiString;
267     dt: TDateTime;
268     begin
269     if aField.IsNull then
270     writeln(OutFile,aField.FieldName,' = NULL')
271     else
272     case aField.DataType of
273     ftArray:
274     begin
275     if not aField.IsNull then
276     WriteArray(TIBArrayField(aField).ArrayIntf);
277     end;
278    
279     ftFloat:
280     writeln(OutFile, aField.FieldName,' = ',FormatFloat('#,##0.000000000000',aField.AsFloat));
281    
282     ftLargeint:
283     writeln(OutFile,aField.FieldName,' = ',aField.AsString);
284    
285     ftmemo, ftBlob:
286     if TBlobField(aField).BlobType = ftMemo then
287     begin
288     s := aField.AsString;
289     if FHexStrings then
290     begin
291     write(OutFile,aField.FieldName,' = ');
292     PrintHexString(s);
293     writeln(OutFile,' (Charset = ',TIBMemoField(aField).CharacterSetName, ' Codepage = ',StringCodePage(s),')');
294     end
295     else
296     begin
297     writeln(OutFile,aField.FieldName,' (Charset = ',TIBMemoField(aField).CharacterSetName, ' Codepage = ',StringCodePage(s),')');
298     writeln(OutFile);
299     writeln(OutFile,s);
300     end
301     end
302     else
303     writeln(OutFile,aField.FieldName,' = (blob), Length = ',TBlobField(aField).BlobSize);
304    
305     ftString:
306     begin
307     s := aField.AsString;
308     if FHexStrings then
309     begin
310     write(OutFile,aField.FieldName,' = ');
311     PrintHexString(s);
312     writeln(OutFile,' (Charset = ',TIBStringField(aField).CharacterSetName, ' Codepage = ',StringCodePage(s),')');
313     end
314     else
315     if (aField is TIBStringField) and (TIBStringField(aField).CharacterSetName <> 'NONE') then
316     writeln(OutFile,aField.FieldName,' = ',s,' (Charset = ',TIBStringField(aField).CharacterSetName, ' Codepage = ',StringCodePage(s),')')
317     else
318     writeln(OutFile,aField.FieldName,' = ',s);
319     end;
320    
321     else
322     writeln(OutFile,aField.FieldName,' = ',aField.AsString);
323     end;
324     end;
325    
326     procedure TIBXTestBase.PrintAffectedRows(query: TIBCustomDataSet);
327     var SelectCount, InsertCount, UpdateCount, DeleteCount: integer;
328     begin
329     if query.GetRowsAffected(SelectCount, InsertCount, UpdateCount, DeleteCount) then
330     begin
331     writeln(OutFile,'Selects = ',SelectCount);
332     writeln(OutFile,'Inserts = ',InsertCount);
333     writeln(OutFile,'Updates = ',UpdateCount);
334     writeln(OutFile,'Deletes = ',DeleteCount);
335     end;
336     end;
337    
338     procedure TIBXTestBase.PrintAffectedRows(query: TIBSQL);
339     var SelectCount, InsertCount, UpdateCount, DeleteCount: integer;
340     begin
341     if query.statement.GetRowsAffected(SelectCount, InsertCount, UpdateCount, DeleteCount) then
342     begin
343     writeln(OutFile,'Selects = ',SelectCount);
344     writeln(OutFile,'Inserts = ',InsertCount);
345     writeln(OutFile,'Updates = ',UpdateCount);
346     writeln(OutFile,'Deletes = ',DeleteCount);
347     end;
348     end;
349    
350     procedure TIBXTestBase.ReadOnlyTransaction;
351     begin
352     FIBTransaction.Params.Clear;
353     FIBTransaction.Params.Add('concurrency');
354     FIBTransaction.Params.Add('wait');
355     FIBTransaction.Params.Add('read');
356     end;
357    
358    
359     procedure TIBXTestBase.ReadWriteTransaction;
360     begin
361     FIBTransaction.Params.Clear;
362     FIBTransaction.Params.Add('concurrency');
363     FIBTransaction.Params.Add('wait');
364     FIBTransaction.Params.Add('write');
365     end;
366    
367     procedure TIBXTestBase.RunScript(aDatabase: TIBDatabase; aFileName: string);
368     begin
369     FIBXScript.Database := aDatabase;
370     aDatabase.DefaultTransaction.Active := true;
371     FIBXScript.Transaction := aDatabase.DefaultTransaction;
372     FIBXScript.RunScript(aFileName);
373     end;
374    
375     procedure TIBXTestBase.ShowStrings(aCaption: string; List: TStrings);
376     var s: string;
377     i: integer;
378     begin
379     s := aCaption + ': ';
380     for i := 0 to List.Count - 1 do
381     begin
382     if i > 0 then
383     s := s + ', ';
384     s := s + List[i];
385     end;
386     writeln(OutFile,s);
387     end;
388    
389     procedure TIBXTestBase.WriteStrings(List: TStrings; limit: integer);
390     var i: integer;
391     begin
392     if Limit <= 0 then
393     Limit := List.Count - 1;
394     for i := 0 to limit do
395     writeln(OutFile,List[i]);
396     writeln(OutFile);
397     end;
398    
399     procedure TIBXTestBase.ExecuteSQL(SQL: string);
400     begin
401     FIBXScript.ExecSQLScript(SQL);
402     end;
403    
404     procedure TIBXTestBase.ShowFBVersion(attachment: IAttachment);
405     var S: TStrings;
406     begin
407     S := TStringList.Create;
408     try
409     attachment.getFBVersion(S);
410     ShowStrings('FB Version',S);
411     finally
412     S.Free;
413     end;
414     end;
415    
416     procedure TIBXTestBase.ShowBoolValue(aValue: integer; WhenTrue,
417     WhenFalse: string);
418     begin
419     if aValue <> 0 then
420     writeln(OutFile,WhenTrue)
421     else
422     writeln(OutFile,WhenFalse);
423     end;
424    
425     procedure TIBXTestBase.ProcessResults;
426     begin
427 tony 402 CompareFiles(FScriptFile,GetOutFile);
428 tony 315 IBDatabase.Connected := false;
429     end;
430    
431     destructor TIBXTestBase.Destroy;
432     begin
433     if IBDatabase <> nil then
434     IBDatabase.Connected := false;
435     inherited Destroy;
436     end;
437    
438 tony 402 procedure TIBXTestBase.CompareFiles(F1, F2: string);
439     var DiffExe: string;
440     Results: string;
441     S: TStringList;
442     ExitStatus: integer;
443     begin
444     if FileExists(F1) and FileExists(F2) then
445     begin
446     DiffExe := GetEnvironmentVariable('DIFF');
447     if DiffExe = '' then
448     DiffExe := 'diff';
449     S := TStringList.Create;
450     try
451     RunCommandInDir(GetCurrentDir,DiffExe ,[F1,F2],Results,ExitStatus);
452     writeln(OutFile,'Run diff command returns ',ExitStatus);
453     if Results <> '' then
454     begin
455     S.Text := Results;
456     writeln(Outfile,'Output from diff command');
457     WriteStrings(S);
458     end;
459     finally
460     S.Free;
461     end;
462     end;
463     end;
464    
465 tony 315 end.
466    

Properties

Name Value
svn:eol-style native