blob: 10ddfc74c1ab5ca3a0743a68a03909e49f6f1427 [file] [log] [blame]
Jens Geyer82fc93e2024-05-24 23:36:07 +02001(*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 *)
19
20unit TestLogger;
21
22{$I ../src/Thrift.Defines.inc}
23
24interface
25
26uses
27 Classes, Windows, SysUtils, Math, ActiveX, ComObj,
28 {$IFDEF SupportsAsync} System.Threading, {$ENDIF}
29 DateUtils,
30 Generics.Collections,
31 TestConstants,
32 ConsoleHelper,
33 Thrift,
34 Thrift.Protocol.Compact,
35 Thrift.Protocol.JSON,
36 Thrift.Protocol,
37 Thrift.Transport.Pipes,
38 Thrift.Transport.WinHTTP,
39 Thrift.Transport.MsxmlHTTP,
40 Thrift.Transport,
41 Thrift.Stream,
42 Thrift.Test,
43 Thrift.WinHTTP,
44 Thrift.Utils,
45 Thrift.Configuration,
46 Thrift.Collections;
47
48
49type
50 TClientTestGroup = (
51 test_Unknown,
52 test_BaseTypes,
53 test_Structs,
54 test_Containers,
55 test_Exceptions
56 // new values here
57 );
58 TClientTestGroups = set of TClientTestGroup;
59
60
61 ITestLogger = interface
62 ['{26693ED5-1469-48AD-B1F3-04281B053DD4}']
63 procedure StartTestGroup( const aGroup : string; const aTest : TClientTestGroup);
64 procedure Expect( aTestResult : Boolean; const aTestInfo : string);
65 procedure QueryTestStats( out failed, executed : TClientTestGroups);
66 procedure ReportResults;
67 end;
68
69
70 // test reporting helper
71 TTestLoggerImpl = class( TInterfacedObject, ITestLogger)
72 strict private
73 FTestGroup : string;
74 FCurrentTest : TClientTestGroup;
75 FSuccesses : Integer;
76 FErrors : TStringList;
77 FFailed : TClientTestGroups;
78 FExecuted : TClientTestGroups;
79
80 strict protected
81 // ITestLogger = interface
82 procedure StartTestGroup( const aGroup : string; const aTest : TClientTestGroup);
83 procedure Expect( aTestResult : Boolean; const aTestInfo : string);
84 procedure QueryTestStats( out failed, executed : TClientTestGroups);
85 procedure ReportResults;
86
87 public
88 constructor Create;
89 destructor Destroy; override;
90
91 end;
92
93
94implementation
95
96
97constructor TTestLoggerImpl.Create;
98begin
99 inherited Create;
100 FCurrentTest := test_Unknown;
101
102 // error list: keep correct order, allow for duplicates
103 FErrors := TStringList.Create;
104 FErrors.Sorted := FALSE;
105 FErrors.Duplicates := dupAccept;
106end;
107
108
109destructor TTestLoggerImpl.Destroy;
110begin
111 try
112 FreeAndNil( FErrors);
113 finally
114 inherited Destroy;
115 end;
116end;
117
118
119procedure TTestLoggerImpl.StartTestGroup( const aGroup : string; const aTest : TClientTestGroup);
120begin
121 FTestGroup := aGroup;
122 FCurrentTest := aTest;
123
124 Include( FExecuted, aTest);
125
126 if FTestGroup <> '' then begin
127 Console.WriteLine('');
128 Console.WriteLine( aGroup+' tests');
129 Console.WriteLine( StringOfChar('-',60));
130 end;
131end;
132
133
134procedure TTestLoggerImpl.Expect( aTestResult : Boolean; const aTestInfo : string);
135begin
136 if aTestResult then begin
137 Inc(FSuccesses);
138 Console.WriteLine( aTestInfo+': passed');
139 end
140 else begin
141 FErrors.Add( FTestGroup+': '+aTestInfo);
142 Include( FFailed, FCurrentTest);
143 Console.WriteLine( aTestInfo+': *** FAILED ***');
144
145 // We have a failed test!
146 // -> issue DebugBreak ONLY if a debugger is attached,
147 // -> unhandled DebugBreaks would cause Windows to terminate the app otherwise
148 if IsDebuggerPresent
149 then {$IFDEF CPUX64} DebugBreak {$ELSE} asm int 3 end {$ENDIF};
150 end;
151end;
152
153
154procedure TTestLoggerImpl.QueryTestStats( out failed, executed : TClientTestGroups);
155begin
156 failed := FFailed;
157 executed := FExecuted;
158end;
159
160
161
162procedure TTestLoggerImpl.ReportResults;
163var nTotal : Integer;
164 sLine : string;
165begin
166 // prevent us from stupid DIV/0 errors
167 nTotal := FSuccesses + FErrors.Count;
168 if nTotal = 0 then begin
169 Console.WriteLine('No results logged');
170 Exit;
171 end;
172
173 Console.WriteLine('');
174 Console.WriteLine( StringOfChar('=',60));
175 Console.WriteLine( IntToStr(nTotal)+' tests performed');
176 Console.WriteLine( IntToStr(FSuccesses)+' tests succeeded ('+IntToStr(round(100*FSuccesses/nTotal))+'%)');
177 Console.WriteLine( IntToStr(FErrors.Count)+' tests failed ('+IntToStr(round(100*FErrors.Count/nTotal))+'%)');
178 Console.WriteLine( StringOfChar('=',60));
179 if FErrors.Count > 0 then begin
180 Console.WriteLine('FAILED TESTS:');
181 for sLine in FErrors do Console.WriteLine('- '+sLine);
182 Console.WriteLine( StringOfChar('=',60));
183 InterlockedIncrement( ExitCode); // return <> 0 on errors
184 end;
185 Console.WriteLine('');
186end;
187
188
189
190
191
192
193end.