Upgrading dependencies to gorealis v2 and thrift 0.12.0
This commit is contained in:
parent
7cbbea498b
commit
54b8d7942a
1327 changed files with 137391 additions and 61476 deletions
519
vendor/git.apache.org/thrift.git/lib/delphi/test/TestClient.pas
generated
vendored
519
vendor/git.apache.org/thrift.git/lib/delphi/test/TestClient.pas
generated
vendored
|
@ -22,15 +22,22 @@ unit TestClient;
|
|||
{$I ../src/Thrift.Defines.inc}
|
||||
|
||||
{.$DEFINE StressTest} // activate to stress-test the server with frequent connects/disconnects
|
||||
{.$DEFINE PerfTest} // activate to activate the performance test
|
||||
{.$DEFINE PerfTest} // activate the performance test
|
||||
{$DEFINE Exceptions} // activate the exceptions test (or disable while debugging)
|
||||
|
||||
{$if CompilerVersion >= 28}
|
||||
{$DEFINE SupportsAsync}
|
||||
{$ifend}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Windows, SysUtils, Classes, Math,
|
||||
Windows, SysUtils, Classes, Math, ComObj, ActiveX,
|
||||
{$IFDEF SupportsAsync} System.Threading, {$ENDIF}
|
||||
DateUtils,
|
||||
Generics.Collections,
|
||||
TestConstants,
|
||||
ConsoleHelper,
|
||||
Thrift,
|
||||
Thrift.Protocol.Compact,
|
||||
Thrift.Protocol.JSON,
|
||||
|
@ -39,8 +46,8 @@ uses
|
|||
Thrift.Transport,
|
||||
Thrift.Stream,
|
||||
Thrift.Test,
|
||||
Thrift.Collections,
|
||||
Thrift.Console;
|
||||
Thrift.Utils,
|
||||
Thrift.Collections;
|
||||
|
||||
type
|
||||
TThreadConsole = class
|
||||
|
@ -52,6 +59,17 @@ type
|
|||
constructor Create( AThread: TThread);
|
||||
end;
|
||||
|
||||
TTestSetup = record
|
||||
protType : TKnownProtocol;
|
||||
endpoint : TEndpointTransport;
|
||||
layered : TLayeredTransports;
|
||||
useSSL : Boolean; // include where appropriate (TLayeredTransport?)
|
||||
host : string;
|
||||
port : Integer;
|
||||
sPipeName : string;
|
||||
hAnonRead, hAnonWrite : THandle;
|
||||
end;
|
||||
|
||||
TClientThread = class( TThread )
|
||||
private type
|
||||
TTestGroup = (
|
||||
|
@ -64,7 +82,15 @@ type
|
|||
);
|
||||
TTestGroups = set of TTestGroup;
|
||||
|
||||
TTestSize = (
|
||||
Empty, // Edge case: the zero-length empty binary
|
||||
Normal, // Fairly small array of usual size (256 bytes)
|
||||
ByteArrayTest, // THRIFT-4454 Large writes/reads may cause range check errors in debug mode
|
||||
PipeWriteLimit // THRIFT-4372 Pipe write operations across a network are limited to 65,535 bytes per write.
|
||||
);
|
||||
|
||||
private
|
||||
FSetup : TTestSetup;
|
||||
FTransport : ITransport;
|
||||
FProtocol : IProtocol;
|
||||
FNumIteration : Integer;
|
||||
|
@ -83,15 +109,25 @@ type
|
|||
function CalculateExitCode : Byte;
|
||||
|
||||
procedure ClientTest;
|
||||
{$IFDEF SupportsAsync}
|
||||
procedure ClientAsyncTest;
|
||||
{$ENDIF}
|
||||
|
||||
procedure InitializeProtocolTransportStack;
|
||||
procedure ShutdownProtocolTransportStack;
|
||||
|
||||
procedure JSONProtocolReadWriteTest;
|
||||
function PrepareBinaryData( aRandomDist : Boolean = FALSE) : TBytes;
|
||||
function PrepareBinaryData( aRandomDist : Boolean; aSize : TTestSize) : TBytes;
|
||||
{$IFDEF StressTest}
|
||||
procedure StressTest(const client : TThriftTest.Iface);
|
||||
{$ENDIF}
|
||||
{$IFDEF Win64}
|
||||
procedure UseInterlockedExchangeAdd64;
|
||||
{$ENDIF}
|
||||
protected
|
||||
procedure Execute; override;
|
||||
public
|
||||
constructor Create( const ATransport: ITransport; const AProtocol : IProtocol; ANumIteration: Integer);
|
||||
constructor Create( const aSetup : TTestSetup; const aNumIteration: Integer);
|
||||
destructor Destroy; override;
|
||||
end;
|
||||
|
||||
|
@ -172,38 +208,27 @@ end;
|
|||
class function TTestClient.Execute(const args: array of string) : Byte;
|
||||
var
|
||||
i : Integer;
|
||||
host : string;
|
||||
port : Integer;
|
||||
sPipeName : string;
|
||||
hAnonRead, hAnonWrite : THandle;
|
||||
threadExitCode : Byte;
|
||||
s : string;
|
||||
threads : array of TThread;
|
||||
dtStart : TDateTime;
|
||||
test : Integer;
|
||||
thread : TThread;
|
||||
trans : ITransport;
|
||||
prot : IProtocol;
|
||||
streamtrans : IStreamTransport;
|
||||
http : IHTTPClient;
|
||||
protType : TKnownProtocol;
|
||||
endpoint : TEndpointTransport;
|
||||
layered : TLayeredTransports;
|
||||
UseSSL : Boolean; // include where appropriate (TLayeredTransport?)
|
||||
const
|
||||
// pipe timeouts to be used
|
||||
DEBUG_TIMEOUT = 30 * 1000;
|
||||
RELEASE_TIMEOUT = DEFAULT_THRIFT_TIMEOUT;
|
||||
TIMEOUT = RELEASE_TIMEOUT;
|
||||
setup : TTestSetup;
|
||||
begin
|
||||
protType := prot_Binary;
|
||||
endpoint := trns_Sockets;
|
||||
layered := [];
|
||||
UseSSL := FALSE;
|
||||
host := 'localhost';
|
||||
port := 9090;
|
||||
sPipeName := '';
|
||||
hAnonRead := INVALID_HANDLE_VALUE;
|
||||
hAnonWrite := INVALID_HANDLE_VALUE;
|
||||
// init record
|
||||
with setup do begin
|
||||
protType := prot_Binary;
|
||||
endpoint := trns_Sockets;
|
||||
layered := [];
|
||||
useSSL := FALSE;
|
||||
host := 'localhost';
|
||||
port := 9090;
|
||||
sPipeName := '';
|
||||
hAnonRead := INVALID_HANDLE_VALUE;
|
||||
hAnonWrite := INVALID_HANDLE_VALUE;
|
||||
end;
|
||||
|
||||
try
|
||||
i := 0;
|
||||
while ( i < Length(args) ) do begin
|
||||
|
@ -218,15 +243,15 @@ begin
|
|||
end
|
||||
else if s = '--host' then begin
|
||||
// --host arg (=localhost) Host to connect
|
||||
host := args[i];
|
||||
setup.host := args[i];
|
||||
Inc( i);
|
||||
end
|
||||
else if s = '--port' then begin
|
||||
// --port arg (=9090) Port number to connect
|
||||
s := args[i];
|
||||
Inc( i);
|
||||
port := StrToIntDef(s,0);
|
||||
if port <= 0 then InvalidArgs;
|
||||
setup.port := StrToIntDef(s,0);
|
||||
if setup.port <= 0 then InvalidArgs;
|
||||
end
|
||||
else if s = '--domain-socket' then begin
|
||||
// --domain-socket arg Domain Socket (e.g. /tmp/ThriftTest.thrift), instead of host and port
|
||||
|
@ -234,27 +259,29 @@ begin
|
|||
end
|
||||
else if s = '--named-pipe' then begin
|
||||
// --named-pipe arg Windows Named Pipe (e.g. MyThriftPipe)
|
||||
endpoint := trns_NamedPipes;
|
||||
sPipeName := args[i];
|
||||
setup.endpoint := trns_NamedPipes;
|
||||
setup.sPipeName := args[i];
|
||||
Inc( i);
|
||||
Console.WriteLine('Using named pipe ('+setup.sPipeName+')');
|
||||
end
|
||||
else if s = '--anon-pipes' then begin
|
||||
// --anon-pipes hRead hWrite Windows Anonymous Pipes pair (handles)
|
||||
endpoint := trns_AnonPipes;
|
||||
hAnonRead := THandle( StrToIntDef( args[i], Integer(INVALID_HANDLE_VALUE)));
|
||||
setup.endpoint := trns_AnonPipes;
|
||||
setup.hAnonRead := THandle( StrToIntDef( args[i], Integer(INVALID_HANDLE_VALUE)));
|
||||
Inc( i);
|
||||
hAnonWrite := THandle( StrToIntDef( args[i], Integer(INVALID_HANDLE_VALUE)));
|
||||
setup.hAnonWrite := THandle( StrToIntDef( args[i], Integer(INVALID_HANDLE_VALUE)));
|
||||
Inc( i);
|
||||
Console.WriteLine('Using anonymous pipes ('+IntToStr(Integer(setup.hAnonRead))+' and '+IntToStr(Integer(setup.hAnonWrite))+')');
|
||||
end
|
||||
else if s = '--transport' then begin
|
||||
// --transport arg (=sockets) Transport: buffered, framed, http, evhttp
|
||||
s := args[i];
|
||||
Inc( i);
|
||||
|
||||
if s = 'buffered' then Include( layered, trns_Buffered)
|
||||
else if s = 'framed' then Include( layered, trns_Framed)
|
||||
else if s = 'http' then endpoint := trns_Http
|
||||
else if s = 'evhttp' then endpoint := trns_AnonPipes
|
||||
if s = 'buffered' then Include( setup.layered, trns_Buffered)
|
||||
else if s = 'framed' then Include( setup.layered, trns_Framed)
|
||||
else if s = 'http' then setup.endpoint := trns_Http
|
||||
else if s = 'evhttp' then setup.endpoint := trns_EvHttp
|
||||
else InvalidArgs;
|
||||
end
|
||||
else if s = '--protocol' then begin
|
||||
|
@ -262,14 +289,14 @@ begin
|
|||
s := args[i];
|
||||
Inc( i);
|
||||
|
||||
if s = 'binary' then protType := prot_Binary
|
||||
else if s = 'compact' then protType := prot_Compact
|
||||
else if s = 'json' then protType := prot_JSON
|
||||
if s = 'binary' then setup.protType := prot_Binary
|
||||
else if s = 'compact' then setup.protType := prot_Compact
|
||||
else if s = 'json' then setup.protType := prot_JSON
|
||||
else InvalidArgs;
|
||||
end
|
||||
else if s = '--ssl' then begin
|
||||
// --ssl Encrypted Transport using SSL
|
||||
UseSSL := TRUE;
|
||||
setup.useSSL := TRUE;
|
||||
|
||||
end
|
||||
else if (s = '-n') or (s = '--testloops') then begin
|
||||
|
@ -295,7 +322,7 @@ begin
|
|||
|
||||
// In the anonymous pipes mode the client is launched by the test server
|
||||
// -> behave nicely and allow for attaching a debugger to this process
|
||||
if (endpoint = trns_AnonPipes) and not IsDebuggerPresent
|
||||
if (setup.endpoint = trns_AnonPipes) and not IsDebuggerPresent
|
||||
then MessageBox( 0, 'Attach Debugger and/or click OK to continue.',
|
||||
'Thrift TestClient (Delphi)',
|
||||
MB_OK or MB_ICONEXCLAMATION);
|
||||
|
@ -303,78 +330,30 @@ begin
|
|||
SetLength( threads, FNumThread);
|
||||
dtStart := Now;
|
||||
|
||||
for test := 0 to FNumThread - 1 do
|
||||
begin
|
||||
case endpoint of
|
||||
trns_Sockets: begin
|
||||
Console.WriteLine('Using sockets ('+host+' port '+IntToStr(port)+')');
|
||||
streamtrans := TSocketImpl.Create( host, port );
|
||||
end;
|
||||
// layered transports are not really meant to be stacked upon each other
|
||||
if (trns_Framed in setup.layered) then begin
|
||||
Console.WriteLine('Using framed transport');
|
||||
end
|
||||
else if (trns_Buffered in setup.layered) then begin
|
||||
Console.WriteLine('Using buffered transport');
|
||||
end;
|
||||
|
||||
trns_Http: begin
|
||||
Console.WriteLine('Using HTTPClient');
|
||||
http := THTTPClientImpl.Create( host);
|
||||
trans := http;
|
||||
end;
|
||||
Console.WriteLine(THRIFT_PROTOCOLS[setup.protType]+' protocol');
|
||||
|
||||
trns_EvHttp: begin
|
||||
raise Exception.Create(ENDPOINT_TRANSPORTS[endpoint]+' transport not implemented');
|
||||
end;
|
||||
|
||||
trns_NamedPipes: begin
|
||||
Console.WriteLine('Using named pipe ('+sPipeName+')');
|
||||
streamtrans := TNamedPipeTransportClientEndImpl.Create( sPipeName, 0, nil, TIMEOUT, TIMEOUT);
|
||||
end;
|
||||
|
||||
trns_AnonPipes: begin
|
||||
Console.WriteLine('Using anonymous pipes ('+IntToStr(Integer(hAnonRead))+' and '+IntToStr(Integer(hAnonWrite))+')');
|
||||
streamtrans := TAnonymousPipeTransportImpl.Create( hAnonRead, hAnonWrite, FALSE);
|
||||
end;
|
||||
|
||||
else
|
||||
raise Exception.Create('Unhandled endpoint transport');
|
||||
end;
|
||||
trans := streamtrans;
|
||||
ASSERT( trans <> nil);
|
||||
|
||||
if (trns_Buffered in layered) then begin
|
||||
trans := TBufferedTransportImpl.Create( streamtrans, 32); // small buffer to test read()
|
||||
Console.WriteLine('Using buffered transport');
|
||||
end;
|
||||
|
||||
if (trns_Framed in layered) then begin
|
||||
trans := TFramedTransportImpl.Create( trans );
|
||||
Console.WriteLine('Using framed transport');
|
||||
end;
|
||||
|
||||
if UseSSL then begin
|
||||
raise Exception.Create('SSL not implemented');
|
||||
end;
|
||||
|
||||
// create protocol instance, default to BinaryProtocol
|
||||
case protType of
|
||||
prot_Binary : prot := TBinaryProtocolImpl.Create( trans, BINARY_STRICT_READ, BINARY_STRICT_WRITE);
|
||||
prot_JSON : prot := TJSONProtocolImpl.Create( trans);
|
||||
prot_Compact : prot := TCompactProtocolImpl.Create( trans);
|
||||
else
|
||||
raise Exception.Create('Unhandled protocol');
|
||||
end;
|
||||
ASSERT( trans <> nil);
|
||||
Console.WriteLine(THRIFT_PROTOCOLS[protType]+' protocol');
|
||||
|
||||
thread := TClientThread.Create( trans, prot, FNumIteration);
|
||||
for test := 0 to FNumThread - 1 do begin
|
||||
thread := TClientThread.Create( setup, FNumIteration);
|
||||
threads[test] := thread;
|
||||
thread.Start;
|
||||
end;
|
||||
|
||||
result := 0;
|
||||
for test := 0 to FNumThread - 1 do begin
|
||||
result := result or threads[test].WaitFor;
|
||||
threadExitCode := threads[test].WaitFor;
|
||||
result := result or threadExitCode;
|
||||
threads[test].Free;
|
||||
threads[test] := nil;
|
||||
end;
|
||||
|
||||
for test := 0 to FNumThread - 1
|
||||
do threads[test].Free;
|
||||
|
||||
Console.Write('Total time: ' + IntToStr( MilliSecondsBetween(Now, dtStart)));
|
||||
|
||||
except
|
||||
|
@ -449,7 +428,8 @@ var
|
|||
looney : IInsanity;
|
||||
first_map : IThriftDictionary<TNumberz, IInsanity>;
|
||||
second_map : IThriftDictionary<TNumberz, IInsanity>;
|
||||
|
||||
pair : TPair<TNumberz, TUserId>;
|
||||
testsize : TTestSize;
|
||||
begin
|
||||
client := TThriftTest.TClient.Create( FProtocol);
|
||||
FTransport.Open;
|
||||
|
@ -458,6 +438,7 @@ begin
|
|||
StressTest( client);
|
||||
{$ENDIF StressTest}
|
||||
|
||||
{$IFDEF Exceptions}
|
||||
// in-depth exception test
|
||||
// (1) do we get an exception at all?
|
||||
// (2) do we get the right exception?
|
||||
|
@ -474,7 +455,7 @@ begin
|
|||
Console.WriteLine( ' = ' + IntToStr(e.ErrorCode) + ', ' + e.Message_ );
|
||||
end;
|
||||
on e:TTransportException do Expect( FALSE, 'Unexpected : "'+e.ToString+'"');
|
||||
on e:Exception do Expect( FALSE, 'Unexpected exception type "'+e.ClassName+'"');
|
||||
on e:Exception do Expect( FALSE, 'Unexpected exception "'+e.ClassName+'": '+e.Message);
|
||||
end;
|
||||
|
||||
// case 2: exception type NOT declared in IDL at the function call
|
||||
|
@ -489,8 +470,8 @@ begin
|
|||
on e:TApplicationException do begin
|
||||
Console.WriteLine( e.ClassName+' = '+e.Message); // this is what we get
|
||||
end;
|
||||
on e:TException do Expect( FALSE, 'Unexpected exception type "'+e.ClassName+'"');
|
||||
on e:Exception do Expect( FALSE, 'Unexpected exception type "'+e.ClassName+'"');
|
||||
on e:TException do Expect( FALSE, 'Unexpected exception "'+e.ClassName+'": '+e.Message);
|
||||
on e:Exception do Expect( FALSE, 'Unexpected exception "'+e.ClassName+'": '+e.Message);
|
||||
end;
|
||||
|
||||
|
||||
|
@ -504,8 +485,9 @@ begin
|
|||
Expect( TRUE, 'testException(''something''): must not trow an exception');
|
||||
except
|
||||
on e:TTransportException do Expect( FALSE, 'Unexpected : "'+e.ToString+'"');
|
||||
on e:Exception do Expect( FALSE, 'Unexpected exception "'+e.ClassName+'"');
|
||||
on e:Exception do Expect( FALSE, 'Unexpected exception "'+e.ClassName+'": '+e.Message);
|
||||
end;
|
||||
{$ENDIF Exceptions}
|
||||
|
||||
|
||||
// simple things
|
||||
|
@ -521,6 +503,9 @@ begin
|
|||
s := client.testString('Test');
|
||||
Expect( s = 'Test', 'testString(''Test'') = "'+s+'"');
|
||||
|
||||
s := client.testString(''); // empty string
|
||||
Expect( s = '', 'testString('''') = "'+s+'"');
|
||||
|
||||
s := client.testString(HUGE_TEST_STRING);
|
||||
Expect( length(s) = length(HUGE_TEST_STRING),
|
||||
'testString( length(HUGE_TEST_STRING) = '+IntToStr(Length(HUGE_TEST_STRING))+') '
|
||||
|
@ -536,16 +521,19 @@ begin
|
|||
i64 := client.testI64(-34359738368);
|
||||
Expect( i64 = -34359738368, 'testI64(-34359738368) = ' + IntToStr( i64));
|
||||
|
||||
binOut := PrepareBinaryData( TRUE);
|
||||
Console.WriteLine('testBinary('+BytesToHex(binOut)+')');
|
||||
try
|
||||
binIn := client.testBinary(binOut);
|
||||
Expect( Length(binOut) = Length(binIn), 'testBinary(): length '+IntToStr(Length(binOut))+' = '+IntToStr(Length(binIn)));
|
||||
i32 := Min( Length(binOut), Length(binIn));
|
||||
Expect( CompareMem( binOut, binIn, i32), 'testBinary('+BytesToHex(binOut)+') = '+BytesToHex(binIn));
|
||||
except
|
||||
on e:TApplicationException do Console.WriteLine('testBinary(): '+e.Message);
|
||||
on e:Exception do Expect( FALSE, 'testBinary(): Unexpected exception "'+e.ClassName+'": '+e.Message);
|
||||
// random binary small
|
||||
for testsize := Low(TTestSize) to High(TTestSize) do begin
|
||||
binOut := PrepareBinaryData( TRUE, testsize);
|
||||
Console.WriteLine('testBinary('+BytesToHex(binOut)+')');
|
||||
try
|
||||
binIn := client.testBinary(binOut);
|
||||
Expect( Length(binOut) = Length(binIn), 'testBinary(): length '+IntToStr(Length(binOut))+' = '+IntToStr(Length(binIn)));
|
||||
i32 := Min( Length(binOut), Length(binIn));
|
||||
Expect( CompareMem( binOut, binIn, i32), 'testBinary('+BytesToHex(binOut)+') = '+BytesToHex(binIn));
|
||||
except
|
||||
on e:TApplicationException do Console.WriteLine('testBinary(): '+e.Message);
|
||||
on e:Exception do Expect( FALSE, 'testBinary(): Unexpected exception "'+e.ClassName+'": '+e.Message);
|
||||
end;
|
||||
end;
|
||||
|
||||
Console.WriteLine('testDouble(5.325098235)');
|
||||
|
@ -772,9 +760,9 @@ begin
|
|||
insane.UserMap.AddOrSetValue( TNumberz.FIVE, 5000);
|
||||
truck := TXtructImpl.Create;
|
||||
truck.String_thing := 'Truck';
|
||||
truck.Byte_thing := 8;
|
||||
truck.I32_thing := 8;
|
||||
truck.I64_thing := 8;
|
||||
truck.Byte_thing := -8; // byte is signed
|
||||
truck.I32_thing := 32;
|
||||
truck.I64_thing := 64;
|
||||
insane.Xtructs := TThriftListImpl<IXtruct>.Create;
|
||||
insane.Xtructs.Add( truck );
|
||||
whoa := client.testInsanity( insane );
|
||||
|
@ -823,6 +811,18 @@ begin
|
|||
end;
|
||||
Console.WriteLine('}');
|
||||
|
||||
(**
|
||||
* So you think you've got this all worked, out eh?
|
||||
*
|
||||
* Creates a the returned map with these values and prints it out:
|
||||
* { 1 => { 2 => argument,
|
||||
* 3 => argument,
|
||||
* },
|
||||
* 2 => { 6 => <empty Insanity struct>, },
|
||||
* }
|
||||
* @return map<UserId, map<Numberz,Insanity>> - a map with the above values
|
||||
*)
|
||||
|
||||
// verify result data
|
||||
Expect( whoa.Count = 2, 'whoa.Count = '+IntToStr(whoa.Count));
|
||||
//
|
||||
|
@ -843,31 +843,20 @@ begin
|
|||
Expect( crazy.__isset_UserMap, 'crazy.__isset_UserMap = '+BoolToString(crazy.__isset_UserMap));
|
||||
Expect( crazy.__isset_Xtructs, 'crazy.__isset_Xtructs = '+BoolToString(crazy.__isset_Xtructs));
|
||||
|
||||
Expect( crazy.UserMap.Count = 2, 'crazy.UserMap.Count = '+IntToStr(crazy.UserMap.Count));
|
||||
Expect( crazy.UserMap[TNumberz.FIVE] = 5, 'crazy.UserMap[TNumberz.FIVE] = '+IntToStr(crazy.UserMap[TNumberz.FIVE]));
|
||||
Expect( crazy.UserMap[TNumberz.EIGHT] = 8, 'crazy.UserMap[TNumberz.EIGHT] = '+IntToStr(crazy.UserMap[TNumberz.EIGHT]));
|
||||
Expect( crazy.UserMap.Count = insane.UserMap.Count, 'crazy.UserMap.Count = '+IntToStr(crazy.UserMap.Count));
|
||||
for pair in insane.UserMap do begin
|
||||
Expect( crazy.UserMap[pair.Key] = pair.Value, 'crazy.UserMap['+IntToStr(Ord(pair.key))+'] = '+IntToStr(crazy.UserMap[pair.Key]));
|
||||
end;
|
||||
|
||||
Expect( crazy.Xtructs.Count = 2, 'crazy.Xtructs.Count = '+IntToStr(crazy.Xtructs.Count));
|
||||
goodbye := crazy.Xtructs[0]; // lists are ordered, so we are allowed to assume this order
|
||||
hello := crazy.Xtructs[1];
|
||||
|
||||
Expect( goodbye.String_thing = 'Goodbye4', 'goodbye.String_thing = "'+goodbye.String_thing+'"');
|
||||
Expect( goodbye.Byte_thing = 4, 'goodbye.Byte_thing = '+IntToStr(goodbye.Byte_thing));
|
||||
Expect( goodbye.I32_thing = 4, 'goodbye.I32_thing = '+IntToStr(goodbye.I32_thing));
|
||||
Expect( goodbye.I64_thing = 4, 'goodbye.I64_thing = '+IntToStr(goodbye.I64_thing));
|
||||
Expect( goodbye.__isset_String_thing, 'goodbye.__isset_String_thing = '+BoolToString(goodbye.__isset_String_thing));
|
||||
Expect( goodbye.__isset_Byte_thing, 'goodbye.__isset_Byte_thing = '+BoolToString(goodbye.__isset_Byte_thing));
|
||||
Expect( goodbye.__isset_I32_thing, 'goodbye.__isset_I32_thing = '+BoolToString(goodbye.__isset_I32_thing));
|
||||
Expect( goodbye.__isset_I64_thing, 'goodbye.__isset_I64_thing = '+BoolToString(goodbye.__isset_I64_thing));
|
||||
|
||||
Expect( hello.String_thing = 'Hello2', 'hello.String_thing = "'+hello.String_thing+'"');
|
||||
Expect( hello.Byte_thing = 2, 'hello.Byte_thing = '+IntToStr(hello.Byte_thing));
|
||||
Expect( hello.I32_thing = 2, 'hello.I32_thing = '+IntToStr(hello.I32_thing));
|
||||
Expect( hello.I64_thing = 2, 'hello.I64_thing = '+IntToStr(hello.I64_thing));
|
||||
Expect( hello.__isset_String_thing, 'hello.__isset_String_thing = '+BoolToString(hello.__isset_String_thing));
|
||||
Expect( hello.__isset_Byte_thing, 'hello.__isset_Byte_thing = '+BoolToString(hello.__isset_Byte_thing));
|
||||
Expect( hello.__isset_I32_thing, 'hello.__isset_I32_thing = '+BoolToString(hello.__isset_I32_thing));
|
||||
Expect( hello.__isset_I64_thing, 'hello.__isset_I64_thing = '+BoolToString(hello.__isset_I64_thing));
|
||||
Expect( crazy.Xtructs.Count = insane.Xtructs.Count, 'crazy.Xtructs.Count = '+IntToStr(crazy.Xtructs.Count));
|
||||
for arg0 := 0 to insane.Xtructs.Count-1 do begin
|
||||
hello := insane.Xtructs[arg0];
|
||||
goodbye := crazy.Xtructs[arg0];
|
||||
Expect( goodbye.String_thing = hello.String_thing, 'goodbye.String_thing = '+goodbye.String_thing);
|
||||
Expect( goodbye.Byte_thing = hello.Byte_thing, 'goodbye.Byte_thing = '+IntToStr(goodbye.Byte_thing));
|
||||
Expect( goodbye.I32_thing = hello.I32_thing, 'goodbye.I32_thing = '+IntToStr(goodbye.I32_thing));
|
||||
Expect( goodbye.I64_thing = hello.I64_thing, 'goodbye.I64_thing = '+IntToStr(goodbye.I64_thing));
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
|
@ -907,7 +896,7 @@ begin
|
|||
Expect( not i.__isset_I64_thing, 'i.__isset_I64_thing = '+BoolToString(i.__isset_I64_thing));
|
||||
}
|
||||
except
|
||||
on e:Exception do Expect( FALSE, 'Unexpected exception "'+e.ClassName+'"');
|
||||
on e:Exception do Expect( FALSE, 'Unexpected exception "'+e.ClassName+'": '+e.Message);
|
||||
end;
|
||||
|
||||
StartTestGroup( 'testMultiException(Xception)', test_Exceptions);
|
||||
|
@ -921,7 +910,7 @@ begin
|
|||
Expect( x.ErrorCode = 1001, 'x.ErrorCode = '+IntToStr(x.ErrorCode));
|
||||
Expect( x.Message_ = 'This is an Xception', 'x.Message = "'+x.Message_+'"');
|
||||
end;
|
||||
on e:Exception do Expect( FALSE, 'Unexpected exception "'+e.ClassName+'"');
|
||||
on e:Exception do Expect( FALSE, 'Unexpected exception "'+e.ClassName+'": '+e.Message);
|
||||
end;
|
||||
|
||||
StartTestGroup( 'testMultiException(Xception2)', test_Exceptions);
|
||||
|
@ -941,7 +930,7 @@ begin
|
|||
Expect( not x.Struct_thing.__isset_I64_thing, 'x.Struct_thing.__isset_I64_thing = '+BoolToString(x.Struct_thing.__isset_I64_thing));
|
||||
}
|
||||
end;
|
||||
on e:Exception do Expect( FALSE, 'Unexpected exception "'+e.ClassName+'"');
|
||||
on e:Exception do Expect( FALSE, 'Unexpected exception "'+e.ClassName+'": '+e.Message);
|
||||
end;
|
||||
|
||||
|
||||
|
@ -966,6 +955,33 @@ begin
|
|||
end;
|
||||
|
||||
|
||||
{$IFDEF SupportsAsync}
|
||||
procedure TClientThread.ClientAsyncTest;
|
||||
var
|
||||
client : TThriftTest.IAsync;
|
||||
s : string;
|
||||
i8 : ShortInt;
|
||||
begin
|
||||
StartTestGroup( 'Async Tests', test_Unknown);
|
||||
client := TThriftTest.TClient.Create( FProtocol);
|
||||
FTransport.Open;
|
||||
|
||||
// oneway void functions
|
||||
client.testOnewayAsync(1).Wait;
|
||||
Expect( TRUE, 'Test Oneway(1)'); // success := no exception
|
||||
|
||||
// normal functions
|
||||
s := client.testStringAsync(HUGE_TEST_STRING).Value;
|
||||
Expect( length(s) = length(HUGE_TEST_STRING),
|
||||
'testString( length(HUGE_TEST_STRING) = '+IntToStr(Length(HUGE_TEST_STRING))+') '
|
||||
+'=> length(result) = '+IntToStr(Length(s)));
|
||||
|
||||
i8 := client.testByte(1).Value;
|
||||
Expect( i8 = 1, 'testByte(1) = ' + IntToStr( i8 ));
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
|
||||
{$IFDEF StressTest}
|
||||
procedure TClientThread.StressTest(const client : TThriftTest.Iface);
|
||||
begin
|
||||
|
@ -986,33 +1002,49 @@ end;
|
|||
{$ENDIF}
|
||||
|
||||
|
||||
function TClientThread.PrepareBinaryData( aRandomDist : Boolean = FALSE) : TBytes;
|
||||
var i, nextPos : Integer;
|
||||
function TClientThread.PrepareBinaryData( aRandomDist : Boolean; aSize : TTestSize) : TBytes;
|
||||
var i : Integer;
|
||||
begin
|
||||
SetLength( result, $100);
|
||||
case aSize of
|
||||
Empty : SetLength( result, 0);
|
||||
Normal : SetLength( result, $100);
|
||||
ByteArrayTest : SetLength( result, SizeOf(TByteArray) + 128);
|
||||
PipeWriteLimit : SetLength( result, 65535 + 128);
|
||||
else
|
||||
raise EArgumentException.Create('aSize');
|
||||
end;
|
||||
|
||||
ASSERT( Low(result) = 0);
|
||||
if Length(result) = 0 then Exit;
|
||||
|
||||
// linear distribution, unless random is requested
|
||||
if not aRandomDist then begin
|
||||
for i := Low(result) to High(result) do begin
|
||||
result[i] := i;
|
||||
result[i] := i mod $100;
|
||||
end;
|
||||
Exit;
|
||||
end;
|
||||
|
||||
// random distribution of all 256 values
|
||||
FillChar( result[0], Length(result) * SizeOf(result[0]), $0);
|
||||
i := 1;
|
||||
while i < Length(result) do begin
|
||||
nextPos := Byte( Random($100));
|
||||
if result[nextPos] = 0 then begin // unused?
|
||||
result[nextPos] := i;
|
||||
Inc(i);
|
||||
end;
|
||||
for i := Low(result) to High(result) do begin
|
||||
result[i] := Byte( Random($100));
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
{$IFDEF Win64}
|
||||
procedure TClientThread.UseInterlockedExchangeAdd64;
|
||||
var a,b : Int64;
|
||||
begin
|
||||
a := 1;
|
||||
b := 2;
|
||||
Thrift.Utils.InterlockedExchangeAdd64( a,b);
|
||||
Expect( a = 3, 'InterlockedExchangeAdd64');
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
|
||||
procedure TClientThread.JSONProtocolReadWriteTest;
|
||||
// Tests only then read/write procedures of the JSON protocol
|
||||
// All tests succeed, if we can read what we wrote before
|
||||
|
@ -1020,8 +1052,8 @@ procedure TClientThread.JSONProtocolReadWriteTest;
|
|||
// other clients or servers expect as the real JSON. This is beyond the scope of this test.
|
||||
var prot : IProtocol;
|
||||
stm : TStringStream;
|
||||
list : IList;
|
||||
binary, binRead : TBytes;
|
||||
list : TThriftList;
|
||||
binary, binRead, emptyBinary : TBytes;
|
||||
i,iErr : Integer;
|
||||
const
|
||||
TEST_SHORT = ShortInt( $FE);
|
||||
|
@ -1043,7 +1075,8 @@ begin
|
|||
StartTestGroup( 'JsonProtocolTest', test_Unknown);
|
||||
|
||||
// prepare binary data
|
||||
binary := PrepareBinaryData( FALSE);
|
||||
binary := PrepareBinaryData( FALSE, Normal);
|
||||
SetLength( emptyBinary, 0); // empty binary data block
|
||||
|
||||
// output setup
|
||||
prot := TJSONProtocolImpl.Create(
|
||||
|
@ -1051,7 +1084,8 @@ begin
|
|||
nil, TThriftStreamAdapterDelphi.Create( stm, FALSE)));
|
||||
|
||||
// write
|
||||
prot.WriteListBegin( TListImpl.Create( TType.String_, 9));
|
||||
Init( list, TType.String_, 9);
|
||||
prot.WriteListBegin( list);
|
||||
prot.WriteBool( TRUE);
|
||||
prot.WriteBool( FALSE);
|
||||
prot.WriteByte( TEST_SHORT);
|
||||
|
@ -1061,6 +1095,8 @@ begin
|
|||
prot.WriteDouble( TEST_DOUBLE);
|
||||
prot.WriteString( TEST_STRING);
|
||||
prot.WriteBinary( binary);
|
||||
prot.WriteString( ''); // empty string
|
||||
prot.WriteBinary( emptyBinary); // empty binary data block
|
||||
prot.WriteListEnd;
|
||||
|
||||
// input setup
|
||||
|
@ -1083,6 +1119,8 @@ begin
|
|||
Expect( abs(prot.ReadDouble-TEST_DOUBLE) < abs(DELTA_DOUBLE), 'WriteDouble/ReadDouble');
|
||||
Expect( prot.ReadString = TEST_STRING, 'WriteString/ReadString');
|
||||
binRead := prot.ReadBinary;
|
||||
Expect( Length(prot.ReadString) = 0, 'WriteString/ReadString (empty string)');
|
||||
Expect( Length(prot.ReadBinary) = 0, 'empty WriteBinary/ReadBinary (empty data block)');
|
||||
prot.ReadListEnd;
|
||||
|
||||
// test binary data
|
||||
|
@ -1219,12 +1257,11 @@ begin
|
|||
end;
|
||||
|
||||
|
||||
constructor TClientThread.Create( const ATransport: ITransport; const AProtocol : IProtocol; ANumIteration: Integer);
|
||||
constructor TClientThread.Create( const aSetup : TTestSetup; const aNumIteration: Integer);
|
||||
begin
|
||||
inherited Create( True );
|
||||
FSetup := aSetup;
|
||||
FNumIteration := ANumIteration;
|
||||
FTransport := ATransport;
|
||||
FProtocol := AProtocol;
|
||||
|
||||
FConsole := TThreadConsole.Create( Self );
|
||||
FCurrentTest := test_Unknown;
|
||||
|
||||
|
@ -1232,6 +1269,8 @@ begin
|
|||
FErrors := TStringList.Create;
|
||||
FErrors.Sorted := FALSE;
|
||||
FErrors.Duplicates := dupAccept;
|
||||
|
||||
inherited Create( TRUE);
|
||||
end;
|
||||
|
||||
destructor TClientThread.Destroy;
|
||||
|
@ -1244,34 +1283,136 @@ end;
|
|||
procedure TClientThread.Execute;
|
||||
var
|
||||
i : Integer;
|
||||
proc : TThreadProcedure;
|
||||
begin
|
||||
// perform all tests
|
||||
try
|
||||
{$IFDEF Win64}
|
||||
UseInterlockedExchangeAdd64;
|
||||
{$ENDIF}
|
||||
JSONProtocolReadWriteTest;
|
||||
for i := 0 to FNumIteration - 1 do
|
||||
begin
|
||||
ClientTest;
|
||||
|
||||
// must be run in the context of the thread
|
||||
InitializeProtocolTransportStack;
|
||||
try
|
||||
for i := 0 to FNumIteration - 1 do begin
|
||||
ClientTest;
|
||||
{$IFDEF SupportsAsync}
|
||||
ClientAsyncTest;
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
// report the outcome
|
||||
ReportResults;
|
||||
SetReturnValue( CalculateExitCode);
|
||||
|
||||
finally
|
||||
ShutdownProtocolTransportStack;
|
||||
end;
|
||||
|
||||
except
|
||||
on e:Exception do Expect( FALSE, 'unexpected exception: "'+e.message+'"');
|
||||
end;
|
||||
end;
|
||||
|
||||
// report the outcome
|
||||
ReportResults;
|
||||
SetReturnValue( CalculateExitCode);
|
||||
|
||||
// shutdown
|
||||
proc := procedure
|
||||
begin
|
||||
if FTransport <> nil then
|
||||
begin
|
||||
procedure TClientThread.InitializeProtocolTransportStack;
|
||||
var
|
||||
streamtrans : IStreamTransport;
|
||||
http : IHTTPClient;
|
||||
sUrl : string;
|
||||
const
|
||||
DEBUG_TIMEOUT = 30 * 1000;
|
||||
RELEASE_TIMEOUT = DEFAULT_THRIFT_TIMEOUT;
|
||||
PIPE_TIMEOUT = RELEASE_TIMEOUT;
|
||||
HTTP_TIMEOUTS = 10 * 1000;
|
||||
begin
|
||||
// needed for HTTP clients as they utilize the MSXML COM components
|
||||
OleCheck( CoInitialize( nil));
|
||||
|
||||
case FSetup.endpoint of
|
||||
trns_Sockets: begin
|
||||
Console.WriteLine('Using sockets ('+FSetup.host+' port '+IntToStr(FSetup.port)+')');
|
||||
streamtrans := TSocketImpl.Create( FSetup.host, FSetup.port );
|
||||
FTransport := streamtrans;
|
||||
end;
|
||||
|
||||
trns_Http: begin
|
||||
Console.WriteLine('Using HTTPClient');
|
||||
if FSetup.useSSL
|
||||
then sUrl := 'http://'
|
||||
else sUrl := 'https://';
|
||||
sUrl := sUrl + FSetup.host;
|
||||
case FSetup.port of
|
||||
80 : if FSetup.useSSL then sUrl := sUrl + ':'+ IntToStr(FSetup.port);
|
||||
443 : if not FSetup.useSSL then sUrl := sUrl + ':'+ IntToStr(FSetup.port);
|
||||
else
|
||||
if FSetup.port > 0 then sUrl := sUrl + ':'+ IntToStr(FSetup.port);
|
||||
end;
|
||||
http := THTTPClientImpl.Create( sUrl);
|
||||
http.DnsResolveTimeout := HTTP_TIMEOUTS;
|
||||
http.ConnectionTimeout := HTTP_TIMEOUTS;
|
||||
http.SendTimeout := HTTP_TIMEOUTS;
|
||||
http.ReadTimeout := HTTP_TIMEOUTS;
|
||||
FTransport := http;
|
||||
end;
|
||||
|
||||
trns_EvHttp: begin
|
||||
raise Exception.Create(ENDPOINT_TRANSPORTS[FSetup.endpoint]+' transport not implemented');
|
||||
end;
|
||||
|
||||
trns_NamedPipes: begin
|
||||
streamtrans := TNamedPipeTransportClientEndImpl.Create( FSetup.sPipeName, 0, nil, PIPE_TIMEOUT, PIPE_TIMEOUT);
|
||||
FTransport := streamtrans;
|
||||
end;
|
||||
|
||||
trns_AnonPipes: begin
|
||||
streamtrans := TAnonymousPipeTransportImpl.Create( FSetup.hAnonRead, FSetup.hAnonWrite, FALSE);
|
||||
FTransport := streamtrans;
|
||||
end;
|
||||
|
||||
else
|
||||
raise Exception.Create('Unhandled endpoint transport');
|
||||
end;
|
||||
ASSERT( FTransport <> nil);
|
||||
|
||||
// layered transports are not really meant to be stacked upon each other
|
||||
if (trns_Framed in FSetup.layered) then begin
|
||||
FTransport := TFramedTransportImpl.Create( FTransport);
|
||||
end
|
||||
else if (trns_Buffered in FSetup.layered) and (streamtrans <> nil) then begin
|
||||
FTransport := TBufferedTransportImpl.Create( streamtrans, 32); // small buffer to test read()
|
||||
end;
|
||||
|
||||
if FSetup.useSSL then begin
|
||||
raise Exception.Create('SSL/TLS not implemented');
|
||||
end;
|
||||
|
||||
// create protocol instance, default to BinaryProtocol
|
||||
case FSetup.protType of
|
||||
prot_Binary : FProtocol := TBinaryProtocolImpl.Create( FTransport, BINARY_STRICT_READ, BINARY_STRICT_WRITE);
|
||||
prot_JSON : FProtocol := TJSONProtocolImpl.Create( FTransport);
|
||||
prot_Compact : FProtocol := TCompactProtocolImpl.Create( FTransport);
|
||||
else
|
||||
raise Exception.Create('Unhandled protocol');
|
||||
end;
|
||||
|
||||
ASSERT( (FTransport <> nil) and (FProtocol <> nil));
|
||||
end;
|
||||
|
||||
|
||||
procedure TClientThread.ShutdownProtocolTransportStack;
|
||||
begin
|
||||
try
|
||||
FProtocol := nil;
|
||||
|
||||
if FTransport <> nil then begin
|
||||
FTransport.Close;
|
||||
FTransport := nil;
|
||||
end;
|
||||
end;
|
||||
|
||||
Synchronize( proc );
|
||||
finally
|
||||
CoUninitialize;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue