Checking in vendor folder for ease of using go get.

This commit is contained in:
Renan DelValle 2018-10-23 23:32:59 -07:00
parent 7a1251853b
commit cdb4b5a1d0
No known key found for this signature in database
GPG key ID: C240AD6D6F443EC9
3554 changed files with 1270116 additions and 0 deletions

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,162 @@
(*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*)
unit TestConstants;
interface
uses SysUtils;
type
TKnownProtocol = (
prot_Binary, // default binary protocol
prot_JSON, // JSON protocol
prot_Compact
);
TServerType = (
srv_Simple,
srv_Nonblocking,
srv_Threadpool,
srv_Threaded
);
TEndpointTransport = (
trns_Sockets,
trns_Http,
trns_NamedPipes,
trns_AnonPipes,
trns_EvHttp // as listed on http://thrift.apache.org/test
);
TLayeredTransport = (
trns_Buffered,
trns_Framed
);
TLayeredTransports = set of TLayeredTransport;
const
SERVER_TYPES : array[TServerType] of string
= ('Simple', 'Nonblocking', 'Threadpool', 'Threaded');
THRIFT_PROTOCOLS : array[TKnownProtocol] of string
= ('Binary', 'JSON', 'Compact');
LAYERED_TRANSPORTS : array[TLayeredTransport] of string
= ('Buffered', 'Framed');
ENDPOINT_TRANSPORTS : array[TEndpointTransport] of string
= ('Sockets', 'Http', 'Named Pipes','Anon Pipes', 'EvHttp');
// defaults are: read=false, write=true
BINARY_STRICT_READ = FALSE;
BINARY_STRICT_WRITE = FALSE;
HUGE_TEST_STRING = 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy '
+ 'eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam '
+ 'voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet '
+ 'clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit '
+ 'amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam '
+ 'nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed '
+ 'diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet '
+ 'clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. '
+ 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy '
+ 'eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam '
+ 'voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet '
+ 'clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit '
+ 'amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam '
+ 'nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed '
+ 'diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet '
+ 'clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. '
+ 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy '
+ 'eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam '
+ 'voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet '
+ 'clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit '
+ 'amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam '
+ 'nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed '
+ 'diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet '
+ 'clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. '
+ 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy '
+ 'eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam '
+ 'voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet '
+ 'clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit '
+ 'amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam '
+ 'nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed '
+ 'diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet '
+ 'clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. '
+ 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy '
+ 'eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam '
+ 'voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet '
+ 'clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit '
+ 'amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam '
+ 'nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed '
+ 'diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet '
+ 'clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. '
+ 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy '
+ 'eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam '
+ 'voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet '
+ 'clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit '
+ 'amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam '
+ 'nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed '
+ 'diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet '
+ 'clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. '
+ 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy '
+ 'eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam '
+ 'voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet '
+ 'clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit '
+ 'amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam '
+ 'nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed '
+ 'diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet '
+ 'clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. '
+ 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy '
+ 'eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam '
+ 'voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet '
+ 'clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit '
+ 'amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam '
+ 'nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed '
+ 'diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet '
+ 'clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. '
+ 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy '
+ 'eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam '
+ 'voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet '
+ 'clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit '
+ 'amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam '
+ 'nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed '
+ 'diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet '
+ 'clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. ';
function BytesToHex( const bytes : TBytes) : string;
implementation
function BytesToHex( const bytes : TBytes) : string;
var i : Integer;
begin
result := '';
for i := Low(bytes) to High(bytes) do begin
result := result + IntToHex(bytes[i],2);
end;
end;
end.

View file

@ -0,0 +1,756 @@
(*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*)
unit TestServer;
{$I ../src/Thrift.Defines.inc}
{$WARN SYMBOL_PLATFORM OFF}
{.$DEFINE RunEndless} // activate to interactively stress-test the server stop routines via Ctrl+C
interface
uses
Windows, SysUtils,
Generics.Collections,
Thrift.Console,
Thrift.Server,
Thrift.Transport,
Thrift.Transport.Pipes,
Thrift.Protocol,
Thrift.Protocol.JSON,
Thrift.Protocol.Compact,
Thrift.Collections,
Thrift.Utils,
Thrift.Test,
Thrift,
TestConstants,
TestServerEvents,
Contnrs;
type
TTestServer = class
public
type
ITestHandler = interface( TThriftTest.Iface )
procedure SetServer( const AServer : IServer );
procedure TestStop;
end;
TTestHandlerImpl = class( TInterfacedObject, ITestHandler )
private
FServer : IServer;
protected
procedure testVoid();
function testBool(thing: Boolean): Boolean;
function testString(const thing: string): string;
function testByte(thing: ShortInt): ShortInt;
function testI32(thing: Integer): Integer;
function testI64(const thing: Int64): Int64;
function testDouble(const thing: Double): Double;
function testBinary(const thing: TBytes): TBytes;
function testStruct(const thing: IXtruct): IXtruct;
function testNest(const thing: IXtruct2): IXtruct2;
function testMap(const thing: IThriftDictionary<Integer, Integer>): IThriftDictionary<Integer, Integer>;
function testStringMap(const thing: IThriftDictionary<string, string>): IThriftDictionary<string, string>;
function testSet(const thing: IHashSet<Integer>): IHashSet<Integer>;
function testList(const thing: IThriftList<Integer>): IThriftList<Integer>;
function testEnum(thing: TNumberz): TNumberz;
function testTypedef(const thing: Int64): Int64;
function testMapMap(hello: Integer): IThriftDictionary<Integer, IThriftDictionary<Integer, Integer>>;
function testInsanity(const argument: IInsanity): IThriftDictionary<Int64, IThriftDictionary<TNumberz, IInsanity>>;
function testMulti(arg0: ShortInt; arg1: Integer; const arg2: Int64; const arg3: IThriftDictionary<SmallInt, string>; arg4: TNumberz; const arg5: Int64): IXtruct;
procedure testException(const arg: string);
function testMultiException(const arg0: string; const arg1: string): IXtruct;
procedure testOneway(secondsToSleep: Integer);
procedure TestStop;
procedure SetServer( const AServer : IServer );
end;
class procedure PrintCmdLineHelp;
class procedure InvalidArgs;
class procedure LaunchAnonPipeChild( const app : string; const transport : IAnonymousPipeServerTransport);
class procedure Execute( const args: array of string);
end;
implementation
var g_Handler : TTestServer.ITestHandler = nil;
function MyConsoleEventHandler( dwCtrlType : DWORD) : BOOL; stdcall;
// Note that this Handler procedure is called from another thread
var handler : TTestServer.ITestHandler;
begin
result := TRUE;
try
case dwCtrlType of
CTRL_C_EVENT : Console.WriteLine( 'Ctrl+C pressed');
CTRL_BREAK_EVENT : Console.WriteLine( 'Ctrl+Break pressed');
CTRL_CLOSE_EVENT : Console.WriteLine( 'Received CloseTask signal');
CTRL_LOGOFF_EVENT : Console.WriteLine( 'Received LogOff signal');
CTRL_SHUTDOWN_EVENT : Console.WriteLine( 'Received Shutdown signal');
else
Console.WriteLine( 'Received console event #'+IntToStr(Integer(dwCtrlType)));
end;
handler := g_Handler;
if handler <> nil then handler.TestStop;
except
// catch all
end;
end;
{ TTestServer.TTestHandlerImpl }
procedure TTestServer.TTestHandlerImpl.SetServer( const AServer: IServer);
begin
FServer := AServer;
end;
function TTestServer.TTestHandlerImpl.testByte(thing: ShortInt): ShortInt;
begin
Console.WriteLine('testByte("' + IntToStr( thing) + '")');
Result := thing;
end;
function TTestServer.TTestHandlerImpl.testDouble( const thing: Double): Double;
begin
Console.WriteLine('testDouble("' + FloatToStr( thing ) + '")');
Result := thing;
end;
function TTestServer.TTestHandlerImpl.testBinary(const thing: TBytes): TBytes;
begin
Console.WriteLine('testBinary("' + BytesToHex( thing ) + '")');
Result := thing;
end;
function TTestServer.TTestHandlerImpl.testEnum(thing: TNumberz): TNumberz;
begin
Console.WriteLine('testEnum(' + IntToStr( Integer( thing)) + ')');
Result := thing;
end;
procedure TTestServer.TTestHandlerImpl.testException(const arg: string);
begin
Console.WriteLine('testException(' + arg + ')');
if ( arg = 'Xception') then
begin
raise TXception.Create( 1001, arg);
end;
if (arg = 'TException') then
begin
raise TException.Create('');
end;
// else do not throw anything
end;
function TTestServer.TTestHandlerImpl.testI32(thing: Integer): Integer;
begin
Console.WriteLine('testI32("' + IntToStr( thing) + '")');
Result := thing;
end;
function TTestServer.TTestHandlerImpl.testI64( const thing: Int64): Int64;
begin
Console.WriteLine('testI64("' + IntToStr( thing) + '")');
Result := thing;
end;
function TTestServer.TTestHandlerImpl.testInsanity(
const argument: IInsanity): IThriftDictionary<Int64, IThriftDictionary<TNumberz, IInsanity>>;
var
hello, goodbye : IXtruct;
crazy : IInsanity;
looney : IInsanity;
first_map : IThriftDictionary<TNumberz, IInsanity>;
second_map : IThriftDictionary<TNumberz, IInsanity>;
insane : IThriftDictionary<Int64, IThriftDictionary<TNumberz, IInsanity>>;
begin
Console.WriteLine('testInsanity()');
hello := TXtructImpl.Create;
hello.String_thing := 'Hello2';
hello.Byte_thing := 2;
hello.I32_thing := 2;
hello.I64_thing := 2;
goodbye := TXtructImpl.Create;
goodbye.String_thing := 'Goodbye4';
goodbye.Byte_thing := 4;
goodbye.I32_thing := 4;
goodbye.I64_thing := 4;
crazy := TInsanityImpl.Create;
crazy.UserMap := TThriftDictionaryImpl<TNumberz, Int64>.Create;
crazy.UserMap.AddOrSetValue( TNumberz.EIGHT, 8);
crazy.Xtructs := TThriftListImpl<IXtruct>.Create;
crazy.Xtructs.Add(goodbye);
looney := TInsanityImpl.Create;
crazy.UserMap.AddOrSetValue( TNumberz.FIVE, 5);
crazy.Xtructs.Add(hello);
first_map := TThriftDictionaryImpl<TNumberz, IInsanity>.Create;
second_map := TThriftDictionaryImpl<TNumberz, IInsanity>.Create;
first_map.AddOrSetValue( TNumberz.TWO, crazy);
first_map.AddOrSetValue( TNumberz.THREE, crazy);
second_map.AddOrSetValue( TNumberz.SIX, looney);
insane := TThriftDictionaryImpl<Int64, IThriftDictionary<TNumberz, IInsanity>>.Create;
insane.AddOrSetValue( 1, first_map);
insane.AddOrSetValue( 2, second_map);
Result := insane;
end;
function TTestServer.TTestHandlerImpl.testList(
const thing: IThriftList<Integer>): IThriftList<Integer>;
var
first : Boolean;
elem : Integer;
begin
Console.Write('testList({');
first := True;
for elem in thing do
begin
if first then
begin
first := False;
end else
begin
Console.Write(', ');
end;
Console.Write( IntToStr( elem));
end;
Console.WriteLine('})');
Result := thing;
end;
function TTestServer.TTestHandlerImpl.testMap(
const thing: IThriftDictionary<Integer, Integer>): IThriftDictionary<Integer, Integer>;
var
first : Boolean;
key : Integer;
begin
Console.Write('testMap({');
first := True;
for key in thing.Keys do
begin
if (first) then
begin
first := false;
end else
begin
Console.Write(', ');
end;
Console.Write(IntToStr(key) + ' => ' + IntToStr( thing[key]));
end;
Console.WriteLine('})');
Result := thing;
end;
function TTestServer.TTestHandlerImpl.TestMapMap(
hello: Integer): IThriftDictionary<Integer, IThriftDictionary<Integer, Integer>>;
var
mapmap : IThriftDictionary<Integer, IThriftDictionary<Integer, Integer>>;
pos : IThriftDictionary<Integer, Integer>;
neg : IThriftDictionary<Integer, Integer>;
i : Integer;
begin
Console.WriteLine('testMapMap(' + IntToStr( hello) + ')');
mapmap := TThriftDictionaryImpl<Integer, IThriftDictionary<Integer, Integer>>.Create;
pos := TThriftDictionaryImpl<Integer, Integer>.Create;
neg := TThriftDictionaryImpl<Integer, Integer>.Create;
for i := 1 to 4 do
begin
pos.AddOrSetValue( i, i);
neg.AddOrSetValue( -i, -i);
end;
mapmap.AddOrSetValue(4, pos);
mapmap.AddOrSetValue( -4, neg);
Result := mapmap;
end;
function TTestServer.TTestHandlerImpl.testMulti(arg0: ShortInt; arg1: Integer;
const arg2: Int64; const arg3: IThriftDictionary<SmallInt, string>;
arg4: TNumberz; const arg5: Int64): IXtruct;
var
hello : IXtruct;
begin
Console.WriteLine('testMulti()');
hello := TXtructImpl.Create;
hello.String_thing := 'Hello2';
hello.Byte_thing := arg0;
hello.I32_thing := arg1;
hello.I64_thing := arg2;
Result := hello;
end;
function TTestServer.TTestHandlerImpl.testMultiException( const arg0, arg1: string): IXtruct;
var
x2 : TXception2;
begin
Console.WriteLine('testMultiException(' + arg0 + ', ' + arg1 + ')');
if ( arg0 = 'Xception') then
begin
raise TXception.Create( 1001, 'This is an Xception'); // test the new rich CTOR
end else
if ( arg0 = 'Xception2') then
begin
x2 := TXception2.Create; // the old way still works too?
x2.ErrorCode := 2002;
x2.Struct_thing := TXtructImpl.Create;
x2.Struct_thing.String_thing := 'This is an Xception2';
x2.UpdateMessageProperty;
raise x2;
end;
Result := TXtructImpl.Create;
Result.String_thing := arg1;
end;
function TTestServer.TTestHandlerImpl.testNest( const thing: IXtruct2): IXtruct2;
var
temp : IXtruct;
begin
temp := thing.Struct_thing;
Console.WriteLine('testNest({' +
IntToStr( thing.Byte_thing) + ', {' +
'"' + temp.String_thing + '", ' +
IntToStr( temp.Byte_thing) + ', ' +
IntToStr( temp.I32_thing) + ', ' +
IntToStr( temp.I64_thing) + '}, ' +
IntToStr( temp.I32_thing) + '})');
Result := thing;
end;
procedure TTestServer.TTestHandlerImpl.testOneway(secondsToSleep: Integer);
begin
Console.WriteLine('testOneway(' + IntToStr( secondsToSleep )+ '), sleeping...');
Sleep(secondsToSleep * 1000);
Console.WriteLine('testOneway finished');
end;
function TTestServer.TTestHandlerImpl.testSet(
const thing: IHashSet<Integer>):IHashSet<Integer>;
var
first : Boolean;
elem : Integer;
begin
Console.Write('testSet({');
first := True;
for elem in thing do
begin
if first then
begin
first := False;
end else
begin
Console.Write( ', ');
end;
Console.Write( IntToStr( elem));
end;
Console.WriteLine('})');
Result := thing;
end;
procedure TTestServer.TTestHandlerImpl.testStop;
begin
if FServer <> nil then
begin
FServer.Stop;
end;
end;
function TTestServer.TTestHandlerImpl.testBool(thing: Boolean): Boolean;
begin
Console.WriteLine('testBool(' + BoolToStr(thing,true) + ')');
Result := thing;
end;
function TTestServer.TTestHandlerImpl.testString( const thing: string): string;
begin
Console.WriteLine('teststring("' + thing + '")');
Result := thing;
end;
function TTestServer.TTestHandlerImpl.testStringMap(
const thing: IThriftDictionary<string, string>): IThriftDictionary<string, string>;
var
first : Boolean;
key : string;
begin
Console.Write('testStringMap({');
first := True;
for key in thing.Keys do
begin
if (first) then
begin
first := false;
end else
begin
Console.Write(', ');
end;
Console.Write(key + ' => ' + thing[key]);
end;
Console.WriteLine('})');
Result := thing;
end;
function TTestServer.TTestHandlerImpl.testTypedef( const thing: Int64): Int64;
begin
Console.WriteLine('testTypedef(' + IntToStr( thing) + ')');
Result := thing;
end;
procedure TTestServer.TTestHandlerImpl.TestVoid;
begin
Console.WriteLine('testVoid()');
end;
function TTestServer.TTestHandlerImpl.testStruct( const thing: IXtruct): IXtruct;
begin
Console.WriteLine('testStruct({' +
'"' + thing.String_thing + '", ' +
IntToStr( thing.Byte_thing) + ', ' +
IntToStr( thing.I32_thing) + ', ' +
IntToStr( thing.I64_thing));
Result := thing;
end;
{ TTestServer }
class procedure TTestServer.PrintCmdLineHelp;
const HELPTEXT = ' [options]'#10
+ #10
+ 'Allowed options:'#10
+ ' -h [ --help ] produce help message'#10
+ ' --port arg (=9090) Port number to listen'#10
+ ' --domain-socket arg Unix Domain Socket (e.g. /tmp/ThriftTest.thrift)'#10
+ ' --named-pipe arg Windows Named Pipe (e.g. MyThriftPipe)'#10
+ ' --server-type arg (=simple) type of server, "simple", "thread-pool",'#10
+ ' "threaded", or "nonblocking"'#10
+ ' --transport arg (=socket) transport: buffered, framed, http, anonpipe'#10
+ ' --protocol arg (=binary) protocol: binary, compact, json'#10
+ ' --ssl Encrypted Transport using SSL'#10
+ ' --processor-events processor-events'#10
+ ' -n [ --workers ] arg (=4) Number of thread pools workers. Only valid for'#10
+ ' thread-pool server type'#10
;
begin
Console.WriteLine( ChangeFileExt(ExtractFileName(ParamStr(0)),'') + HELPTEXT);
end;
class procedure TTestServer.InvalidArgs;
begin
Console.WriteLine( 'Invalid args.');
Console.WriteLine( ChangeFileExt(ExtractFileName(ParamStr(0)),'') + ' -h for more information');
Abort;
end;
class procedure TTestServer.LaunchAnonPipeChild( const app : string; const transport : IAnonymousPipeServerTransport);
//Launch child process and pass R/W anonymous pipe handles on cmd line.
//This is a simple example and does not include elevation or other
//advanced features.
var pi : PROCESS_INFORMATION;
si : STARTUPINFO;
sArg, sHandles, sCmdLine : string;
i : Integer;
begin
GetStartupInfo( si); //set startupinfo for the spawned process
// preformat handles args
sHandles := Format( '%d %d',
[ Integer(transport.ClientAnonRead),
Integer(transport.ClientAnonWrite)]);
// pass all settings to client
sCmdLine := app;
for i := 1 to ParamCount do begin
sArg := ParamStr(i);
// add anonymous handles and quote strings where appropriate
if sArg = '-anon'
then sArg := sArg +' '+ sHandles
else begin
if Pos(' ',sArg) > 0
then sArg := '"'+sArg+'"';
end;;
sCmdLine := sCmdLine +' '+ sArg;
end;
// spawn the child process
Console.WriteLine('Starting client '+sCmdLine);
Win32Check( CreateProcess( nil, PChar(sCmdLine), nil,nil,TRUE,0,nil,nil,si,pi));
CloseHandle( pi.hThread);
CloseHandle( pi.hProcess);
end;
class procedure TTestServer.Execute( const args: array of string);
var
Port : Integer;
ServerEvents : Boolean;
sPipeName : string;
testHandler : ITestHandler;
testProcessor : IProcessor;
ServerTrans : IServerTransport;
ServerEngine : IServer;
anonymouspipe : IAnonymousPipeServerTransport;
namedpipe : INamedPipeServerTransport;
TransportFactory : ITransportFactory;
ProtocolFactory : IProtocolFactory;
i, numWorker : Integer;
s : string;
protType : TKnownProtocol;
servertype : TServerType;
endpoint : TEndpointTransport;
layered : TLayeredTransports;
UseSSL : Boolean; // include where appropriate (TLayeredTransport?)
begin
try
ServerEvents := FALSE;
protType := prot_Binary;
servertype := srv_Simple;
endpoint := trns_Sockets;
layered := [];
UseSSL := FALSE;
Port := 9090;
sPipeName := '';
numWorker := 4;
i := 0;
while ( i < Length(args) ) do begin
s := args[i];
Inc(i);
// Allowed options:
if (s = '-h') or (s = '--help') then begin
// -h [ --help ] produce help message
PrintCmdLineHelp;
Exit;
end
else if (s = '--port') then begin
// --port arg (=9090) Port number to listen
s := args[i];
Inc(i);
Port := StrToIntDef( s, Port);
end
else if (s = '--domain-socket') then begin
// --domain-socket arg Unix Domain Socket (e.g. /tmp/ThriftTest.thrift)
raise Exception.Create('domain-socket not supported');
end
else if (s = '--named-pipe') then begin
// --named-pipe arg Windows Named Pipe (e.g. MyThriftPipe)
endpoint := trns_NamedPipes;
sPipeName := args[i]; // -pipe <name>
Inc( i );
end
else if (s = '--server-type') then begin
// --server-type arg (=simple) type of server,
// arg = "simple", "thread-pool", "threaded", or "nonblocking"
s := args[i];
Inc(i);
if s = 'simple' then servertype := srv_Simple
else if s = 'thread-pool' then servertype := srv_Threadpool
else if s = 'threaded' then servertype := srv_Threaded
else if s = 'nonblocking' then servertype := srv_Nonblocking
else InvalidArgs;
end
else if (s = '--transport') then begin
// --transport arg (=buffered) transport: buffered, framed, http
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 = 'anonpipe' then endpoint := trns_AnonPipes
else InvalidArgs;
end
else if (s = '--protocol') then begin
// --protocol arg (=binary) protocol: binary, compact, json
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
else InvalidArgs;
end
else if (s = '--ssl') then begin
// --ssl Encrypted Transport using SSL
UseSSL := TRUE;
end
else if (s = '--processor-events') then begin
// --processor-events processor-events
ServerEvents := TRUE;
end
else if (s = '-n') or (s = '--workers') then begin
// -n [ --workers ] arg (=4) Number of thread pools workers.
// Only valid for thread-pool server type
s := args[i];
numWorker := StrToIntDef(s,0);
if numWorker > 0
then Inc(i)
else numWorker := 4;
end
else begin
InvalidArgs;
end;
end;
Console.WriteLine('Server configuration: ');
// create protocol factory, default to BinaryProtocol
case protType of
prot_Binary : ProtocolFactory := TBinaryProtocolImpl.TFactory.Create( BINARY_STRICT_READ, BINARY_STRICT_WRITE);
prot_JSON : ProtocolFactory := TJSONProtocolImpl.TFactory.Create;
prot_Compact : ProtocolFactory := TCompactProtocolImpl.TFactory.Create;
else
raise Exception.Create('Unhandled protocol');
end;
ASSERT( ProtocolFactory <> nil);
Console.WriteLine('- '+THRIFT_PROTOCOLS[protType]+' protocol');
case endpoint of
trns_Sockets : begin
Console.WriteLine('- sockets (port '+IntToStr(port)+')');
if (trns_Buffered in layered) then Console.WriteLine('- buffered');
servertrans := TServerSocketImpl.Create( Port, 0, (trns_Buffered in layered));
end;
trns_Http : begin
raise Exception.Create(ENDPOINT_TRANSPORTS[endpoint]+' server transport not implemented');
end;
trns_NamedPipes : begin
Console.WriteLine('- named pipe ('+sPipeName+')');
namedpipe := TNamedPipeServerTransportImpl.Create( sPipeName, 4096, PIPE_UNLIMITED_INSTANCES);
servertrans := namedpipe;
end;
trns_AnonPipes : begin
Console.WriteLine('- anonymous pipes');
anonymouspipe := TAnonymousPipeServerTransportImpl.Create;
servertrans := anonymouspipe;
end
else
raise Exception.Create('Unhandled endpoint transport');
end;
ASSERT( servertrans <> nil);
if UseSSL then begin
raise Exception.Create('SSL not implemented');
end;
if (trns_Framed in layered) then begin
Console.WriteLine('- framed transport');
TransportFactory := TFramedTransportImpl.TFactory.Create
end
else begin
TransportFactory := TTransportFactoryImpl.Create;
end;
ASSERT( TransportFactory <> nil);
testHandler := TTestHandlerImpl.Create;
testProcessor := TThriftTest.TProcessorImpl.Create( testHandler );
case servertype of
srv_Simple : begin
ServerEngine := TSimpleServer.Create( testProcessor, ServerTrans, TransportFactory, ProtocolFactory);
end;
srv_Nonblocking : begin
raise Exception.Create(SERVER_TYPES[servertype]+' server not implemented');
end;
srv_Threadpool,
srv_Threaded: begin
if numWorker > 1 then {use here};
raise Exception.Create(SERVER_TYPES[servertype]+' server not implemented');
end;
else
raise Exception.Create('Unhandled server type');
end;
ASSERT( ServerEngine <> nil);
testHandler.SetServer( ServerEngine);
// test events?
if ServerEvents then begin
Console.WriteLine('- server events test enabled');
ServerEngine.ServerEvents := TServerEventsImpl.Create;
end;
// start the client now when we have the anon handles, but before the server starts
if endpoint = trns_AnonPipes
then LaunchAnonPipeChild( ExtractFilePath(ParamStr(0))+'client.exe', anonymouspipe);
// install Ctrl+C handler before the server starts
g_Handler := testHandler;
SetConsoleCtrlHandler( @MyConsoleEventHandler, TRUE);
Console.WriteLine('');
repeat
Console.WriteLine('Starting the server ...');
serverEngine.Serve;
until {$IFDEF RunEndless} FALSE {$ELSE} TRUE {$ENDIF};
testHandler.SetServer( nil);
g_Handler := nil;
except
on E: EAbort do raise;
on E: Exception do begin
Console.WriteLine( E.Message + #10 + E.StackTrace );
end;
end;
Console.WriteLine( 'done.');
end;
end.

View file

@ -0,0 +1,174 @@
(*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*)
unit TestServerEvents;
interface
uses
SysUtils,
Thrift,
Thrift.Protocol,
Thrift.Transport,
Thrift.Server,
Thrift.Console;
type
TRequestEventsImpl = class( TInterfacedObject, IRequestEvents)
protected
FStart : TDateTime;
// IRequestProcessingEvents
procedure PreRead;
procedure PostRead;
procedure PreWrite;
procedure PostWrite;
procedure OnewayComplete;
procedure UnhandledError( const e : Exception);
procedure CleanupContext;
public
constructor Create;
end;
TProcessorEventsImpl = class( TInterfacedObject, IProcessorEvents)
protected
FReqs : Integer;
// IProcessorEvents
procedure Processing( const transport : ITransport);
function CreateRequestContext( const aFunctionName : string) : IRequestEvents;
procedure CleanupContext;
public
constructor Create;
end;
TServerEventsImpl = class( TInterfacedObject, IServerEvents)
protected
// IServerEvents
procedure PreServe;
procedure PreAccept;
function CreateProcessingContext( const input, output : IProtocol) : IProcessorEvents;
end;
implementation
{ TServerEventsImpl }
procedure TServerEventsImpl.PreServe;
begin
Console.WriteLine('ServerEvents: Server starting to serve requests');
end;
procedure TServerEventsImpl.PreAccept;
begin
Console.WriteLine('ServerEvents: Server transport is ready to accept incoming calls');
end;
function TServerEventsImpl.CreateProcessingContext(const input, output: IProtocol): IProcessorEvents;
begin
result := TProcessorEventsImpl.Create;
end;
{ TProcessorEventsImpl }
constructor TProcessorEventsImpl.Create;
begin
inherited Create;
FReqs := 0;
Console.WriteLine('ProcessorEvents: Client connected, processing begins');
end;
procedure TProcessorEventsImpl.Processing(const transport: ITransport);
begin
Console.WriteLine('ProcessorEvents: Processing of incoming request begins');
end;
function TProcessorEventsImpl.CreateRequestContext( const aFunctionName: string): IRequestEvents;
begin
result := TRequestEventsImpl.Create;
Inc( FReqs);
end;
procedure TProcessorEventsImpl.CleanupContext;
begin
Console.WriteLine( 'ProcessorEvents: completed after handling '+IntToStr(FReqs)+' requests.');
end;
{ TRequestEventsImpl }
constructor TRequestEventsImpl.Create;
begin
inherited Create;
FStart := Now;
Console.WriteLine('RequestEvents: New request');
end;
procedure TRequestEventsImpl.PreRead;
begin
Console.WriteLine('RequestEvents: Reading request message ...');
end;
procedure TRequestEventsImpl.PostRead;
begin
Console.WriteLine('RequestEvents: Reading request message completed');
end;
procedure TRequestEventsImpl.PreWrite;
begin
Console.WriteLine('RequestEvents: Writing response message ...');
end;
procedure TRequestEventsImpl.PostWrite;
begin
Console.WriteLine('RequestEvents: Writing response message completed');
end;
procedure TRequestEventsImpl.OnewayComplete;
begin
Console.WriteLine('RequestEvents: Oneway message processed');
end;
procedure TRequestEventsImpl.UnhandledError(const e: Exception);
begin
Console.WriteLine('RequestEvents: Unhandled exception of type '+e.classname);
end;
procedure TRequestEventsImpl.CleanupContext;
var millis : Double;
begin
millis := (Now - FStart) * (24*60*60*1000);
Console.WriteLine( 'Request processing completed in '+IntToStr(Round(millis))+' ms');
end;
end.

View file

@ -0,0 +1,72 @@
(*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*)
program client;
{$APPTYPE CONSOLE}
uses
SysUtils,
TestClient in 'TestClient.pas',
Thrift.Test, // in 'gen-delphi\Thrift.Test.pas',
Thrift in '..\src\Thrift.pas',
Thrift.Transport in '..\src\Thrift.Transport.pas',
Thrift.Socket in '..\src\Thrift.Socket.pas',
Thrift.Transport.Pipes in '..\src\Thrift.Transport.Pipes.pas',
Thrift.Protocol in '..\src\Thrift.Protocol.pas',
Thrift.Protocol.JSON in '..\src\Thrift.Protocol.JSON.pas',
Thrift.Protocol.Compact in '..\src\Thrift.Protocol.Compact.pas',
Thrift.Protocol.Multiplex in '..\src\Thrift.Protocol.Multiplex.pas',
Thrift.Collections in '..\src\Thrift.Collections.pas',
Thrift.Server in '..\src\Thrift.Server.pas',
Thrift.Stream in '..\src\Thrift.Stream.pas',
Thrift.Console in '..\src\Thrift.Console.pas',
Thrift.TypeRegistry in '..\src\Thrift.TypeRegistry.pas',
Thrift.Utils in '..\src\Thrift.Utils.pas';
var
nParamCount : Integer;
args : array of string;
i : Integer;
arg : string;
begin
try
Writeln( 'Delphi TestClient '+Thrift.Version);
nParamCount := ParamCount;
SetLength( args, nParamCount);
for i := 1 to nParamCount do begin
arg := ParamStr( i );
args[i-1] := arg;
end;
ExitCode := TTestClient.Execute( args);
except
on E: EAbort do begin
ExitCode := $FF;
end;
on E: Exception do begin
Writeln(E.ClassName, ': ', E.Message);
ExitCode := $FF;
end;
end;
end.

View file

@ -0,0 +1,28 @@
How to use the test case:
----------------------------------------------
- copy and the template batch file
- open the batch file and adjust configuration as necessary
- run the batch
Configuration:
----------------------------------------------
SVNWORKDIR
should point to the Thrift working copy root
MY_THRIFT_FILES
can be set to point to a folder with more thrift IDL files.
If you don't have any such files, just leave the setting blank.
BIN
Local MSYS binary folder. Your THRIFT.EXE is installed here.
MINGW_BIN
Local MinGW bin folder. Contains DLL files required by THRIFT.EXE
DCC
Identifies the Delphi Command Line compiler (dcc32.exe)
To be configuired only, if the default is not suitable.
----------------------------------------------
*EOF*

View file

@ -0,0 +1,55 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
// make sure generated code does not produce name collisions with predefined keywords
typedef i32 Cardinal
typedef string message
typedef list< map< Cardinal, message>> program
struct unit {
1: Cardinal downto;
2: program procedure;
}
typedef set< unit> units
exception exception1 {
1: program message;
2: unit array;
}
service constructor {
unit Create(1: Cardinal asm; 2: message inherited) throws (1: exception1 label);
units Destroy();
}
const Cardinal downto = +1
const Cardinal published = -1
enum keywords {
record = 1,
repeat = 2,
deprecated = 3
}

View file

@ -0,0 +1,173 @@
REM /*
REM * Licensed to the Apache Software Foundation (ASF) under one
REM * or more contributor license agreements. See the NOTICE file
REM * distributed with this work for additional information
REM * regarding copyright ownership. The ASF licenses this file
REM * to you under the Apache License, Version 2.0 (the
REM * "License"); you may not use this file except in compliance
REM * with the License. You may obtain a copy of the License at
REM *
REM * http://www.apache.org/licenses/LICENSE-2.0
REM *
REM * Unless required by applicable law or agreed to in writing,
REM * software distributed under the License is distributed on an
REM * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
REM * KIND, either express or implied. See the License for the
REM * specific language governing permissions and limitations
REM * under the License.
REM */
@echo off
if ""=="%1" goto CONFIG
goto HANDLEDIR
REM -----------------------------------------------------
:CONFIG
REM -----------------------------------------------------
rem * CONFIGURATION BEGIN
rem * configuration settings, adjust as necessary to meet your system setup
set SVNWORKDIR=
set MY_THRIFT_FILES=
set BIN=C:\MSys10\local\bin
set MINGW_BIN=C:\MinGW\bin
set DCC=
set SUBDIR=gen-delphi
rem * CONFIGURATION END
REM -----------------------------------------------------
:START
REM -----------------------------------------------------
rem * configured?
if "%SVNWORKDIR%"=="" goto CONFIG_ERROR
rem * try to find dcc32.exe
echo Looking for dcc32.exe ...
if not exist "%DCC%" set DCC=%ProgramFiles%\Embarcadero\RAD Studio\8.0\bin\dcc32.exe
if not exist "%DCC%" set DCC=%ProgramFiles(x86)%\Embarcadero\RAD Studio\8.0\bin\dcc32.exe
if not exist "%DCC%" goto CONFIG_ERROR
echo Found %DCC%
echo.
rem * some helpers
set PATH=%BIN%;%MINGW_BIN%;%PATH%
set TARGET=%SVNWORKDIR%\..\thrift-testing
set SOURCE=%SVNWORKDIR%
set TESTAPP=TestProject
set UNITSEARCH=%SOURCE%\lib\pas\src;%SOURCE%\lib\delphi\src
set OUTDCU="%TARGET%\dcu"
set LOGFILE=%TARGET%\%SUBDIR%\codegen.log
rem * create and/or empty target dirs
if not exist "%TARGET%" md "%TARGET%"
if not exist "%TARGET%\%SUBDIR%" md "%TARGET%\%SUBDIR%"
if not exist "%OUTDCU%" md "%OUTDCU%"
if exist "%TARGET%\*.thrift" del "%TARGET%\*.thrift" /Q
if exist "%TARGET%\%SUBDIR%\*.*" del "%TARGET%\%SUBDIR%\*.*" /Q
if exist "%OUTDCU%\*.*" del "%OUTDCU%\*.*" /Q
rem * recurse through thrift WC and "my thrift files" folder
rem * copies all .thrift files into thrift-testing
call %0 %SOURCE%
if not "%MY_THRIFT_FILES%"=="" call %0 %MY_THRIFT_FILES%
rem * compile all thrift files, generate PAS and C++ code
echo.
echo Generating code, please wait ...
cd "%TARGET%"
for %%a in (*.thrift) do "%BIN%\thrift.exe" -v --gen delphi:register_types,constprefix,events,xmldoc "%%a" 2>> "%LOGFILE%"
REM * for %%a in (*.thrift) do "%BIN%\thrift.exe" -v --gen cpp "%%a" >> NUL:
cmd /c start notepad "%LOGFILE%"
cd ..
rem * check for special Delphi testcases being processed
if not exist "%TARGET%\%SUBDIR%\ReservedKeywords.pas" goto TESTCASE_MISSING
rem * generate a minimal DPR file that uses all generated pascal units
cd "%TARGET%\%SUBDIR%\"
if exist inherited.* ren inherited.* _inherited.*
echo program %TESTAPP%; > %TESTAPP%.dpr
echo {$APPTYPE CONSOLE} >> %TESTAPP%.dpr
echo. >> %TESTAPP%.dpr
echo uses >> %TESTAPP%.dpr
for %%a in (*.pas) do echo %%~na, >> %TESTAPP%.dpr
echo Windows, Classes, SysUtils; >> %TESTAPP%.dpr
echo. >> %TESTAPP%.dpr
echo begin >> %TESTAPP%.dpr
echo Writeln('Successfully compiled!'); >> %TESTAPP%.dpr
echo Writeln('List of units:'); >> %TESTAPP%.dpr
for %%a in (*.pas) do echo Write('%%~na':30,'':10); >> %TESTAPP%.dpr
echo Writeln; >> %TESTAPP%.dpr
echo end. >> %TESTAPP%.dpr
echo. >> %TESTAPP%.dpr
cd ..\..
rem * try to compile the DPR
rem * this should not throw any errors, warnings or hints
"%DCC%" -B "%TARGET%\%SUBDIR%\%TESTAPP%" -U"%UNITSEARCH%" -I"%UNITSEARCH%" -N"%OUTDCU%" -E"%TARGET%\%SUBDIR%"
dir "%TARGET%\%SUBDIR%\%TESTAPP%.exe"
if not exist "%TARGET%\%SUBDIR%\%TESTAPP%.exe" goto CODEGEN_FAILED
echo.
echo -----------------------------------------------------------------
echo The compiled program is now executed. If it hangs or crashes, we
echo have a serious problem with the generated code. Expected output
echo is "Successfully compiled:" followed by a list of generated units.
echo -----------------------------------------------------------------
"%TARGET%\%SUBDIR%\%TESTAPP%.exe"
echo -----------------------------------------------------------------
echo.
pause
GOTO EOF
REM -----------------------------------------------------
:DXE_NOT_FOUND
REM -----------------------------------------------------
echo Delphi Compiler (dcc32.exe) not found.
echo Please check the "DCC" setting in this batch.
echo.
cmd /c start notepad README.MD
cmd /c start notepad %0
pause
GOTO EOF
REM -----------------------------------------------------
:CONFIG_ERROR
REM -----------------------------------------------------
echo Missing, incomplete or wrong configuration settings!
cmd /c start notepad README.MD
cmd /c start notepad %0
pause
GOTO EOF
REM -----------------------------------------------------
:TESTCASE_MISSING
REM -----------------------------------------------------
echo Missing an expected Delphi testcase!
pause
GOTO EOF
REM -----------------------------------------------------
:CODEGEN_FAILED
REM -----------------------------------------------------
echo Code generation FAILED!
pause
GOTO EOF
REM -----------------------------------------------------
:HANDLEDIR
REM -----------------------------------------------------
REM echo %1
for /D %%a in (%1\*) do call %0 %%a
if exist "%1\*.thrift" copy /b "%1\*.thrift" "%TARGET%\*.*"
GOTO EOF
REM -----------------------------------------------------
:EOF
REM -----------------------------------------------------

23
vendor/git.apache.org/thrift.git/lib/delphi/test/maketest.sh generated vendored Executable file
View file

@ -0,0 +1,23 @@
#!/bin/sh
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
../../../compiler/cpp/thrift --gen delphi -o . ../../../test/ThriftTest.thrift

View file

@ -0,0 +1,131 @@
(*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*)
unit Multiplex.Client.Main;
{.$DEFINE StressTest} // activate to stress-test the server with frequent connects/disconnects
{.$DEFINE PerfTest} // activate to activate the performance test
interface
uses
Windows, SysUtils, Classes,
DateUtils,
Generics.Collections,
Thrift,
Thrift.Protocol,
Thrift.Protocol.Multiplex,
Thrift.Transport.Pipes,
Thrift.Transport,
Thrift.Stream,
Thrift.Collections,
Benchmark, // in gen-delphi folder
Aggr, // in gen-delphi folder
Multiplex.Test.Common;
type
TTestClient = class
protected
FProtocol : IProtocol;
procedure ParseArgs( const args: array of string);
procedure Setup;
procedure Run;
public
constructor Create( const args: array of string);
class procedure Execute( const args: array of string);
end;
implementation
type
IServiceClient = interface
['{7745C1C2-AB20-43BA-B6F0-08BF92DE0BAC}']
procedure Test;
end;
//--- TTestClient -------------------------------------
class procedure TTestClient.Execute( const args: array of string);
var client : TTestClient;
begin
client := TTestClient.Create(args);
try
client.Run;
finally
client.Free;
end;
end;
constructor TTestClient.Create( const args: array of string);
begin
inherited Create;
ParseArgs(args);
Setup;
end;
procedure TTestClient.ParseArgs( const args: array of string);
begin
if Length(args) <> 0
then raise Exception.Create('No args accepted so far');
end;
procedure TTestClient.Setup;
var trans : ITransport;
begin
trans := TSocketImpl.Create( 'localhost', 9090);
trans := TFramedTransportImpl.Create( trans);
trans.Open;
FProtocol := TBinaryProtocolImpl.Create( trans, TRUE, TRUE);
end;
procedure TTestClient.Run;
var bench : TBenchmarkService.Iface;
aggr : TAggr.Iface;
multiplex : IProtocol;
i : Integer;
begin
try
multiplex := TMultiplexedProtocol.Create( FProtocol, NAME_BENCHMARKSERVICE);
bench := TBenchmarkService.TClient.Create( multiplex);
multiplex := TMultiplexedProtocol.Create( FProtocol, NAME_AGGR);
aggr := TAggr.TClient.Create( multiplex);
for i := 1 to 10
do aggr.addValue( bench.fibonacci(i));
for i in aggr.getValues
do Write(IntToStr(i)+' ');
WriteLn;
except
on e:Exception do Writeln(#10+e.Message);
end;
end;
end.

View file

@ -0,0 +1,201 @@
(*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*)
unit Multiplex.Server.Main;
{$WARN SYMBOL_PLATFORM OFF}
{.$DEFINE RunEndless} // activate to interactively stress-test the server stop routines via Ctrl+C
interface
uses
Windows, SysUtils,
Generics.Collections,
Thrift.Console,
Thrift.Server,
Thrift.Transport,
Thrift.Transport.Pipes,
Thrift.Protocol,
Thrift.Protocol.Multiplex,
Thrift.Processor.Multiplex,
Thrift.Collections,
Thrift.Utils,
Thrift,
Benchmark, // in gen-delphi folder
Aggr, // in gen-delphi folder
Multiplex.Test.Common,
Contnrs;
type
TTestServer = class
public type
ITestHandler = interface
['{CAE09AAB-80FB-48E9-B3A8-7F9B96F5419A}']
procedure SetServer( const AServer : IServer );
end;
protected type
TTestHandlerImpl = class( TInterfacedObject, ITestHandler)
private
FServer : IServer;
protected
// ITestHandler
procedure SetServer( const AServer : IServer );
property Server : IServer read FServer write SetServer;
end;
TBenchmarkServiceImpl = class( TTestHandlerImpl, TBenchmarkService.Iface)
protected
// TBenchmarkService.Iface
function fibonacci(n: ShortInt): Integer;
end;
TAggrImpl = class( TTestHandlerImpl, TAggr.Iface)
protected
FList : IThriftList<Integer>;
// TAggr.Iface
procedure addValue(value: Integer);
function getValues(): IThriftList<Integer>;
public
constructor Create;
destructor Destroy; override;
end;
public
class procedure Execute( const args: array of string);
end;
implementation
{ TTestServer.TTestHandlerImpl }
procedure TTestServer.TTestHandlerImpl.SetServer( const AServer: IServer);
begin
FServer := AServer;
end;
{ TTestServer.TBenchmarkServiceImpl }
function TTestServer.TBenchmarkServiceImpl.fibonacci(n: ShortInt): Integer;
var prev, next : Integer;
begin
prev := 0;
result := 1;
while n > 0 do begin
next := result + prev;
prev := result;
result := next;
Dec(n);
end;
end;
{ TTestServer.TAggrImpl }
constructor TTestServer.TAggrImpl.Create;
begin
inherited Create;
FList := TThriftListImpl<Integer>.Create;
end;
destructor TTestServer.TAggrImpl.Destroy;
begin
try
FreeAndNil( FList);
finally
inherited Destroy;
end;
end;
procedure TTestServer.TAggrImpl.addValue(value: Integer);
begin
FList.Add( value);
end;
function TTestServer.TAggrImpl.getValues(): IThriftList<Integer>;
begin
result := FList;
end;
{ TTestServer }
class procedure TTestServer.Execute( const args: array of string);
var
TransportFactory : ITransportFactory;
ProtocolFactory : IProtocolFactory;
ServerTrans : IServerTransport;
benchHandler : TBenchmarkService.Iface;
aggrHandler : TAggr.Iface;
benchProcessor : IProcessor;
aggrProcessor : IProcessor;
multiplex : IMultiplexedProcessor;
ServerEngine : IServer;
begin
try
// create protocol factory, default to BinaryProtocol
ProtocolFactory := TBinaryProtocolImpl.TFactory.Create( TRUE, TRUE);
servertrans := TServerSocketImpl.Create( 9090, 0, FALSE);
TransportFactory := TFramedTransportImpl.TFactory.Create;
benchHandler := TBenchmarkServiceImpl.Create;
benchProcessor := TBenchmarkService.TProcessorImpl.Create( benchHandler);
aggrHandler := TAggrImpl.Create;
aggrProcessor := TAggr.TProcessorImpl.Create( aggrHandler);
multiplex := TMultiplexedProcessorImpl.Create;
multiplex.RegisterProcessor( NAME_BENCHMARKSERVICE, benchProcessor);
multiplex.RegisterProcessor( NAME_AGGR, aggrProcessor);
ServerEngine := TSimpleServer.Create( multiplex,
ServerTrans,
TransportFactory,
ProtocolFactory);
(benchHandler as ITestHandler).SetServer( ServerEngine);
(aggrHandler as ITestHandler).SetServer( ServerEngine);
Console.WriteLine('Starting the server ...');
ServerEngine.serve();
(benchHandler as ITestHandler).SetServer( nil);
(aggrHandler as ITestHandler).SetServer( nil);
except
on E: Exception do
begin
Console.Write( E.Message);
end;
end;
Console.WriteLine( 'done.');
end;
end.

View file

@ -0,0 +1,67 @@
(*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*)
program Multiplex.Test.Client;
{$APPTYPE CONSOLE}
uses
SysUtils,
Multiplex.Client.Main in 'Multiplex.Client.Main.pas',
Thrift in '..\..\src\Thrift.pas',
Thrift.Socket in '..\..\src\Thrift.Socket.pas',
Thrift.Transport in '..\..\src\Thrift.Transport.pas',
Thrift.Transport.Pipes in '..\..\src\Thrift.Transport.Pipes.pas',
Thrift.Protocol in '..\..\src\Thrift.Protocol.pas',
Thrift.Protocol.Multiplex in '..\..\src\Thrift.Protocol.Multiplex.pas',
Thrift.Collections in '..\..\src\Thrift.Collections.pas',
Thrift.Server in '..\..\src\Thrift.Server.pas',
Thrift.Stream in '..\..\src\Thrift.Stream.pas',
Thrift.Console in '..\..\src\Thrift.Console.pas',
Thrift.TypeRegistry in '..\..\src\Thrift.TypeRegistry.pas',
Thrift.Utils in '..\..\src\Thrift.Utils.pas';
var
nParamCount : Integer;
args : array of string;
i : Integer;
arg : string;
s : string;
begin
try
Writeln( 'Multiplex TestClient '+Thrift.Version);
nParamCount := ParamCount;
SetLength( args, nParamCount);
for i := 1 to nParamCount do
begin
arg := ParamStr( i );
args[i-1] := arg;
end;
TTestClient.Execute( args );
Readln;
except
on E: Exception do begin
Writeln(E.ClassName, ': ', E.Message);
ExitCode := $FFFF;
end;
end;
end.

View file

@ -0,0 +1,35 @@
(*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*)
unit Multiplex.Test.Common;
interface
const
NAME_BENCHMARKSERVICE = 'BenchmarkService';
NAME_AGGR = 'Aggr';
implementation
// nix
end.

View file

@ -0,0 +1,67 @@
(*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*)
program Multiplex.Test.Server;
{$APPTYPE CONSOLE}
uses
SysUtils,
Multiplex.Server.Main in 'Multiplex.Server.Main.pas',
Thrift in '..\..\src\Thrift.pas',
Thrift.Socket in '..\..\src\Thrift.Socket.pas',
Thrift.Transport in '..\..\src\Thrift.Transport.pas',
Thrift.Transport.Pipes in '..\..\src\Thrift.Transport.Pipes.pas',
Thrift.Protocol in '..\..\src\Thrift.Protocol.pas',
Thrift.Protocol.Multiplex in '..\..\src\Thrift.Protocol.Multiplex.pas',
Thrift.Processor.Multiplex in '..\..\src\Thrift.Processor.Multiplex.pas',
Thrift.Collections in '..\..\src\Thrift.Collections.pas',
Thrift.Server in '..\..\src\Thrift.Server.pas',
Thrift.Console in '..\..\src\Thrift.Console.pas',
Thrift.Utils in '..\..\src\Thrift.Utils.pas',
Thrift.TypeRegistry in '..\..\src\Thrift.TypeRegistry.pas',
Thrift.Stream in '..\..\src\Thrift.Stream.pas';
var
nParamCount : Integer;
args : array of string;
i : Integer;
arg : string;
s : string;
begin
try
Writeln( 'Multiplex TestServer '+Thrift.Version);
nParamCount := ParamCount;
SetLength( args, nParamCount);
for i := 1 to nParamCount do
begin
arg := ParamStr( i );
args[i-1] := arg;
end;
TTestServer.Execute( args );
Writeln('Press ENTER to close ... '); Readln;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.

View file

@ -0,0 +1,349 @@
(*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*)
unit TestSerializer.Data;
interface
uses
Thrift.Collections,
DebugProtoTest;
type
Fixtures = class
public
class function CreateOneOfEach : IOneOfEach;
class function CreateNesting : INesting;
class function CreateHolyMoley : IHolyMoley;
class function CreateCompactProtoTestStruct : ICompactProtoTestStruct;
// These byte arrays are serialized versions of the above structs.
// They were serialized in binary protocol using thrift 0.6.x and are used to
// test backwards compatibility with respect to the standard scheme.
(*
all data copied from JAVA version,
to be used later
public static final byte[] persistentBytesOneOfEach = new byte[] {
$02, $00, $01, $01, $02, $00, $02, $00, $03, $00,
$03, $D6, $06, $00, $04, $69, $78, $08, $00, $05,
$01, $00, $00, $00, $0A, $00, $06, $00, $00, $00,
$01, $65, $A0, $BC, $00, $04, $00, $07, $40, $09,
$21, $FB, $54, $44, $2D, $18, $0B, $00, $08, $00,
$00, $00, $0D, $4A, $53, $4F, $4E, $20, $54, $48,
$49, $53, $21, $20, $22, $01, $0B, $00, $09, $00,
$00, $00, $2E, $D3, $80, $E2, $85, $AE, $CE, $9D,
$20, $D0, $9D, $CE, $BF, $E2, $85, $BF, $D0, $BE,
$C9, $A1, $D0, $B3, $D0, $B0, $CF, $81, $E2, $84,
$8E, $20, $CE, $91, $74, $74, $CE, $B1, $E2, $85,
$BD, $CE, $BA, $EF, $BF, $BD, $E2, $80, $BC, $02,
$00, $0A, $00, $0B, $00, $0B, $00, $00, $00, $06,
$62, $61, $73, $65, $36, $34, $0F, $00, $0C, $03,
$00, $00, $00, $03, $01, $02, $03, $0F, $00, $0D,
$06, $00, $00, $00, $03, $00, $01, $00, $02, $00,
$03, $0F, $00, $0E, $0A, $00, $00, $00, $03, $00,
$00, $00, $00, $00, $00, $00, $01, $00, $00, $00,
$00, $00, $00, $00, $02, $00, $00, $00, $00, $00,
$00, $00, $03, $00 };
public static final byte[] persistentBytesNesting = new byte[] {
$0C, $00, $01, $08, $00, $01, $00, $00, $7A, $69,
$0B, $00, $02, $00, $00, $00, $13, $49, $20, $61,
$6D, $20, $61, $20, $62, $6F, $6E, $6B, $2E, $2E,
$2E, $20, $78, $6F, $72, $21, $00, $0C, $00, $02,
$02, $00, $01, $01, $02, $00, $02, $00, $03, $00,
$03, $D6, $06, $00, $04, $69, $78, $08, $00, $05,
$01, $00, $00, $00, $0A, $00, $06, $00, $00, $00,
$01, $65, $A0, $BC, $00, $04, $00, $07, $40, $09,
$21, $FB, $54, $44, $2D, $18, $0B, $00, $08, $00,
$00, $00, $0D, $4A, $53, $4F, $4E, $20, $54, $48,
$49, $53, $21, $20, $22, $01, $0B, $00, $09, $00,
$00, $00, $2E, $D3, $80, $E2, $85, $AE, $CE, $9D,
$20, $D0, $9D, $CE, $BF, $E2, $85, $BF, $D0, $BE,
$C9, $A1, $D0, $B3, $D0, $B0, $CF, $81, $E2, $84,
$8E, $20, $CE, $91, $74, $74, $CE, $B1, $E2, $85,
$BD, $CE, $BA, $EF, $BF, $BD, $E2, $80, $BC, $02,
$00, $0A, $00, $0B, $00, $0B, $00, $00, $00, $06,
$62, $61, $73, $65, $36, $34, $0F, $00, $0C, $03,
$00, $00, $00, $03, $01, $02, $03, $0F, $00, $0D,
$06, $00, $00, $00, $03, $00, $01, $00, $02, $00,
$03, $0F, $00, $0E, $0A, $00, $00, $00, $03, $00,
$00, $00, $00, $00, $00, $00, $01, $00, $00, $00,
$00, $00, $00, $00, $02, $00, $00, $00, $00, $00,
$00, $00, $03, $00, $00 };
public static final byte[] persistentBytesHolyMoley = new byte[] {
$0F, $00, $01, $0C, $00, $00, $00, $02, $02, $00,
$01, $01, $02, $00, $02, $00, $03, $00, $03, $23,
$06, $00, $04, $69, $78, $08, $00, $05, $01, $00,
$00, $00, $0A, $00, $06, $00, $00, $00, $01, $65,
$A0, $BC, $00, $04, $00, $07, $40, $09, $21, $FB,
$54, $44, $2D, $18, $0B, $00, $08, $00, $00, $00,
$0D, $4A, $53, $4F, $4E, $20, $54, $48, $49, $53,
$21, $20, $22, $01, $0B, $00, $09, $00, $00, $00,
$2E, $D3, $80, $E2, $85, $AE, $CE, $9D, $20, $D0,
$9D, $CE, $BF, $E2, $85, $BF, $D0, $BE, $C9, $A1,
$D0, $B3, $D0, $B0, $CF, $81, $E2, $84, $8E, $20,
$CE, $91, $74, $74, $CE, $B1, $E2, $85, $BD, $CE,
$BA, $EF, $BF, $BD, $E2, $80, $BC, $02, $00, $0A,
$00, $0B, $00, $0B, $00, $00, $00, $06, $62, $61,
$73, $65, $36, $34, $0F, $00, $0C, $03, $00, $00,
$00, $03, $01, $02, $03, $0F, $00, $0D, $06, $00,
$00, $00, $03, $00, $01, $00, $02, $00, $03, $0F,
$00, $0E, $0A, $00, $00, $00, $03, $00, $00, $00,
$00, $00, $00, $00, $01, $00, $00, $00, $00, $00,
$00, $00, $02, $00, $00, $00, $00, $00, $00, $00,
$03, $00, $02, $00, $01, $01, $02, $00, $02, $00,
$03, $00, $03, $D6, $06, $00, $04, $69, $78, $08,
$00, $05, $01, $00, $00, $00, $0A, $00, $06, $00,
$00, $00, $01, $65, $A0, $BC, $00, $04, $00, $07,
$40, $09, $21, $FB, $54, $44, $2D, $18, $0B, $00,
$08, $00, $00, $00, $0D, $4A, $53, $4F, $4E, $20,
$54, $48, $49, $53, $21, $20, $22, $01, $0B, $00,
$09, $00, $00, $00, $2E, $D3, $80, $E2, $85, $AE,
$CE, $9D, $20, $D0, $9D, $CE, $BF, $E2, $85, $BF,
$D0, $BE, $C9, $A1, $D0, $B3, $D0, $B0, $CF, $81,
$E2, $84, $8E, $20, $CE, $91, $74, $74, $CE, $B1,
$E2, $85, $BD, $CE, $BA, $EF, $BF, $BD, $E2, $80,
$BC, $02, $00, $0A, $00, $0B, $00, $0B, $00, $00,
$00, $06, $62, $61, $73, $65, $36, $34, $0F, $00,
$0C, $03, $00, $00, $00, $03, $01, $02, $03, $0F,
$00, $0D, $06, $00, $00, $00, $03, $00, $01, $00,
$02, $00, $03, $0F, $00, $0E, $0A, $00, $00, $00,
$03, $00, $00, $00, $00, $00, $00, $00, $01, $00,
$00, $00, $00, $00, $00, $00, $02, $00, $00, $00,
$00, $00, $00, $00, $03, $00, $0E, $00, $02, $0F,
$00, $00, $00, $03, $0B, $00, $00, $00, $00, $0B,
$00, $00, $00, $03, $00, $00, $00, $0F, $74, $68,
$65, $6E, $20, $61, $20, $6F, $6E, $65, $2C, $20,
$74, $77, $6F, $00, $00, $00, $06, $74, $68, $72,
$65, $65, $21, $00, $00, $00, $06, $46, $4F, $55,
$52, $21, $21, $0B, $00, $00, $00, $02, $00, $00,
$00, $09, $61, $6E, $64, $20, $61, $20, $6F, $6E,
$65, $00, $00, $00, $09, $61, $6E, $64, $20, $61,
$20, $74, $77, $6F, $0D, $00, $03, $0B, $0F, $00,
$00, $00, $03, $00, $00, $00, $03, $74, $77, $6F,
$0C, $00, $00, $00, $02, $08, $00, $01, $00, $00,
$00, $01, $0B, $00, $02, $00, $00, $00, $05, $57,
$61, $69, $74, $2E, $00, $08, $00, $01, $00, $00,
$00, $02, $0B, $00, $02, $00, $00, $00, $05, $57,
$68, $61, $74, $3F, $00, $00, $00, $00, $05, $74,
$68, $72, $65, $65, $0C, $00, $00, $00, $00, $00,
$00, $00, $04, $7A, $65, $72, $6F, $0C, $00, $00,
$00, $00, $00 };
*)
private
const
kUnicodeBytes : packed array[0..43] of Byte
= ( $d3, $80, $e2, $85, $ae, $ce, $9d, $20, $d0, $9d,
$ce, $bf, $e2, $85, $bf, $d0, $be, $c9, $a1, $d0,
$b3, $d0, $b0, $cf, $81, $e2, $84, $8e, $20, $ce,
$91, $74, $74, $ce, $b1, $e2, $85, $bd, $ce, $ba,
$83, $e2, $80, $bc);
end;
implementation
class function Fixtures.CreateOneOfEach : IOneOfEach;
var db : Double;
us : Utf8String;
begin
result := TOneOfEachImpl.Create;
result.setIm_true( TRUE);
result.setIm_false( FALSE);
result.setA_bite( ShortInt($D6));
result.setInteger16( 27000);
result.setInteger32( 1 shl 24);
result.setInteger64( Int64(6000) * Int64(1000) * Int64(1000));
db := Pi;
result.setDouble_precision( db);
result.setSome_characters( 'JSON THIS! \"\1');
// ??
SetLength( us, Length(kUnicodeBytes));
Move( kUnicodeBytes[0], us[1], Length(kUnicodeBytes));
// ??
SetString( us, PChar(@kUnicodeBytes[0]), Length(kUnicodeBytes));
// !!
result.setZomg_unicode( UnicodeString( us));
{$IF cDebugProtoTest_Option_AnsiStr_Binary}
result.SetBase64('base64');
{$ELSE}
not yet impl
{$IFEND}
// byte, i16, and i64 lists are populated by default constructor
end;
class function Fixtures.CreateNesting : INesting;
var bonk : IBonk;
begin
bonk := TBonkImpl.Create;
bonk.Type_ := 31337;
bonk.Message := 'I am a bonk... xor!';
result := TNestingImpl.Create;
result.My_bonk := bonk;
result.My_ooe := CreateOneOfEach;
end;
class function Fixtures.CreateHolyMoley : IHolyMoley;
var big : IThriftList<IOneOfEach>;
stage1 : IThriftList<String>;
stage2 : IThriftList<IBonk>;
b : IBonk;
begin
result := THolyMoleyImpl.Create;
big := TThriftListImpl<IOneOfEach>.Create;
big.add( CreateOneOfEach);
big.add( CreateNesting.my_ooe);
result.Big := big;
result.Big[0].setA_bite( $22);
result.Big[0].setA_bite( $23);
result.Contain := THashSetImpl< IThriftList<string>>.Create;
stage1 := TThriftListImpl<String>.Create;
stage1.add( 'and a one');
stage1.add( 'and a two');
result.Contain.add( stage1);
stage1 := TThriftListImpl<String>.Create;
stage1.add( 'then a one, two');
stage1.add( 'three!');
stage1.add( 'FOUR!!');
result.Contain.add( stage1);
stage1 := TThriftListImpl<String>.Create;
result.Contain.add( stage1);
stage2 := TThriftListImpl<IBonk>.Create;
result.Bonks := TThriftDictionaryImpl< String, IThriftList< IBonk>>.Create;
// one empty
result.Bonks.Add( 'zero', stage2);
// one with two
stage2 := TThriftListImpl<IBonk>.Create;
b := TBonkImpl.Create;
b.type_ := 1;
b.message := 'Wait.';
stage2.Add( b);
b := TBonkImpl.Create;
b.type_ := 2;
b.message := 'What?';
stage2.Add( b);
result.Bonks.Add( 'two', stage2);
// one with three
stage2 := TThriftListImpl<IBonk>.Create;
b := TBonkImpl.Create;
b.type_ := 3;
b.message := 'quoth';
stage2.Add( b);
b := TBonkImpl.Create;
b.type_ := 4;
b.message := 'the raven';
stage2.Add( b);
b := TBonkImpl.Create;
b.type_ := 5;
b.message := 'nevermore';
stage2.Add( b);
result.bonks.Add( 'three', stage2);
end;
class function Fixtures.CreateCompactProtoTestStruct : ICompactProtoTestStruct;
// superhuge compact proto test struct
begin
result := TCompactProtoTestStructImpl.Create;
result.A_byte := TDebugProtoTestConstants.COMPACT_TEST.A_byte;
result.A_i16 := TDebugProtoTestConstants.COMPACT_TEST.A_i16;
result.A_i32 := TDebugProtoTestConstants.COMPACT_TEST.A_i32;
result.A_i64 := TDebugProtoTestConstants.COMPACT_TEST.A_i64;
result.A_double := TDebugProtoTestConstants.COMPACT_TEST.A_double;
result.A_string := TDebugProtoTestConstants.COMPACT_TEST.A_string;
result.A_binary := TDebugProtoTestConstants.COMPACT_TEST.A_binary;
result.True_field := TDebugProtoTestConstants.COMPACT_TEST.True_field;
result.False_field := TDebugProtoTestConstants.COMPACT_TEST.False_field;
result.Empty_struct_field := TDebugProtoTestConstants.COMPACT_TEST.Empty_struct_field;
result.Byte_list := TDebugProtoTestConstants.COMPACT_TEST.Byte_list;
result.I16_list := TDebugProtoTestConstants.COMPACT_TEST.I16_list;
result.I32_list := TDebugProtoTestConstants.COMPACT_TEST.I32_list;
result.I64_list := TDebugProtoTestConstants.COMPACT_TEST.I64_list;
result.Double_list := TDebugProtoTestConstants.COMPACT_TEST.Double_list;
result.String_list := TDebugProtoTestConstants.COMPACT_TEST.String_list;
result.Binary_list := TDebugProtoTestConstants.COMPACT_TEST.Binary_list;
result.Boolean_list := TDebugProtoTestConstants.COMPACT_TEST.Boolean_list;
result.Struct_list := TDebugProtoTestConstants.COMPACT_TEST.Struct_list;
result.Byte_set := TDebugProtoTestConstants.COMPACT_TEST.Byte_set;
result.I16_set := TDebugProtoTestConstants.COMPACT_TEST.I16_set;
result.I32_set := TDebugProtoTestConstants.COMPACT_TEST.I32_set;
result.I64_set := TDebugProtoTestConstants.COMPACT_TEST.I64_set;
result.Double_set := TDebugProtoTestConstants.COMPACT_TEST.Double_set;
result.String_set := TDebugProtoTestConstants.COMPACT_TEST.String_set;
result.String_set := TDebugProtoTestConstants.COMPACT_TEST.String_set;
result.String_set := TDebugProtoTestConstants.COMPACT_TEST.String_set;
result.Binary_set := TDebugProtoTestConstants.COMPACT_TEST.Binary_set;
result.Boolean_set := TDebugProtoTestConstants.COMPACT_TEST.Boolean_set;
result.Struct_set := TDebugProtoTestConstants.COMPACT_TEST.Struct_set;
result.Byte_byte_map := TDebugProtoTestConstants.COMPACT_TEST.Byte_byte_map;
result.I16_byte_map := TDebugProtoTestConstants.COMPACT_TEST.I16_byte_map;
result.I32_byte_map := TDebugProtoTestConstants.COMPACT_TEST.I32_byte_map;
result.I64_byte_map := TDebugProtoTestConstants.COMPACT_TEST.I64_byte_map;
result.Double_byte_map := TDebugProtoTestConstants.COMPACT_TEST.Double_byte_map;
result.String_byte_map := TDebugProtoTestConstants.COMPACT_TEST.String_byte_map;
result.Binary_byte_map := TDebugProtoTestConstants.COMPACT_TEST.Binary_byte_map;
result.Boolean_byte_map := TDebugProtoTestConstants.COMPACT_TEST.Boolean_byte_map;
result.Byte_i16_map := TDebugProtoTestConstants.COMPACT_TEST.Byte_i16_map;
result.Byte_i32_map := TDebugProtoTestConstants.COMPACT_TEST.Byte_i32_map;
result.Byte_i64_map := TDebugProtoTestConstants.COMPACT_TEST.Byte_i64_map;
result.Byte_double_map := TDebugProtoTestConstants.COMPACT_TEST.Byte_double_map;
result.Byte_string_map := TDebugProtoTestConstants.COMPACT_TEST.Byte_string_map;
result.Byte_binary_map := TDebugProtoTestConstants.COMPACT_TEST.Byte_binary_map;
result.Byte_boolean_map := TDebugProtoTestConstants.COMPACT_TEST.Byte_boolean_map;
result.List_byte_map := TDebugProtoTestConstants.COMPACT_TEST.List_byte_map;
result.Set_byte_map := TDebugProtoTestConstants.COMPACT_TEST.Set_byte_map;
result.Map_byte_map := TDebugProtoTestConstants.COMPACT_TEST.Map_byte_map;
result.Byte_map_map := TDebugProtoTestConstants.COMPACT_TEST.Byte_map_map;
result.Byte_set_map := TDebugProtoTestConstants.COMPACT_TEST.Byte_set_map;
result.Byte_list_map := TDebugProtoTestConstants.COMPACT_TEST.Byte_list_map;
{$IF cDebugProtoTest_Option_AnsiStr_Binary}
result.A_binary := AnsiString( #0#1#2#3#4#5#6#7#8);
{$ELSE}
not yet impl
{$IFEND}
end;
end.

View file

@ -0,0 +1,230 @@
(*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*)
program TestSerializer;
{$APPTYPE CONSOLE}
uses
Classes, Windows, SysUtils, Generics.Collections,
Thrift in '..\..\src\Thrift.pas',
Thrift.Socket in '..\..\src\Thrift.Socket.pas',
Thrift.Transport in '..\..\src\Thrift.Transport.pas',
Thrift.Protocol in '..\..\src\Thrift.Protocol.pas',
Thrift.Protocol.JSON in '..\..\src\Thrift.Protocol.JSON.pas',
Thrift.Collections in '..\..\src\Thrift.Collections.pas',
Thrift.Server in '..\..\src\Thrift.Server.pas',
Thrift.Console in '..\..\src\Thrift.Console.pas',
Thrift.Utils in '..\..\src\Thrift.Utils.pas',
Thrift.Serializer in '..\..\src\Thrift.Serializer.pas',
Thrift.Stream in '..\..\src\Thrift.Stream.pas',
Thrift.TypeRegistry in '..\..\src\Thrift.TypeRegistry.pas',
DebugProtoTest,
TestSerializer.Data;
type
TTestSerializer = class //extends TestCase {
private
FProtocols : TList< IProtocolFactory>;
class function Serialize(const input : IBase; const factory : IProtocolFactory) : TBytes; overload;
class procedure Serialize(const input : IBase; const factory : IProtocolFactory; const aStream : TStream); overload;
class procedure Deserialize( const input : TBytes; const target : IBase; const factory : IProtocolFactory); overload;
class procedure Deserialize( const input : TStream; const target : IBase; const factory : IProtocolFactory); overload;
procedure Test_Serializer_Deserializer;
public
constructor Create;
destructor Destroy; override;
procedure RunTests;
end;
{ TTestSerializer }
constructor TTestSerializer.Create;
begin
inherited Create;
FProtocols := TList< IProtocolFactory>.Create;
FProtocols.Add( TBinaryProtocolImpl.TFactory.Create);
//FProtocols.Add( TCompactProtocolImpl.TFactory.Create);
FProtocols.Add( TJSONProtocolImpl.TFactory.Create);
end;
destructor TTestSerializer.Destroy;
begin
try
FreeAndNil( FProtocols);
finally
inherited Destroy;
end;
end;
type TMethod = (mt_Bytes, mt_Stream);
procedure TTestSerializer.Test_Serializer_Deserializer;
var level3ooe, correct : IOneOfEach;
factory : IProtocolFactory;
bytes : TBytes;
stream : TFileStream;
i : Integer;
method : TMethod;
begin
correct := Fixtures.CreateOneOfEach;
stream := TFileStream.Create( 'TestSerializer.dat', fmCreate);
try
for method in [Low(TMethod)..High(TMethod)] do begin
for factory in FProtocols do begin
// write
level3ooe := Fixtures.CreateOneOfEach;
case method of
mt_Bytes: bytes := Serialize( level3ooe, factory);
mt_Stream: begin
stream.Size := 0;
Serialize( level3ooe, factory, stream);
end
else
ASSERT( FALSE);
end;
// init + read
level3ooe := TOneOfEachImpl.Create;
case method of
mt_Bytes: Deserialize( bytes, level3ooe, factory);
mt_Stream: begin
stream.Position := 0;
Deserialize( stream, level3ooe, factory);
end
else
ASSERT( FALSE);
end;
// check
ASSERT( level3ooe.Im_true = correct.Im_true);
ASSERT( level3ooe.Im_false = correct.Im_false);
ASSERT( level3ooe.A_bite = correct.A_bite);
ASSERT( level3ooe.Integer16 = correct.Integer16);
ASSERT( level3ooe.Integer32 = correct.Integer32);
ASSERT( level3ooe.Integer64 = correct.Integer64);
ASSERT( Abs( level3ooe.Double_precision - correct.Double_precision) < 1E-12);
ASSERT( level3ooe.Some_characters = correct.Some_characters);
ASSERT( level3ooe.Zomg_unicode = correct.Zomg_unicode);
ASSERT( level3ooe.What_who = correct.What_who);
ASSERT( level3ooe.Base64 = correct.Base64);
ASSERT( level3ooe.Byte_list.Count = correct.Byte_list.Count);
for i := 0 to level3ooe.Byte_list.Count-1
do ASSERT( level3ooe.Byte_list[i] = correct.Byte_list[i]);
ASSERT( level3ooe.I16_list.Count = correct.I16_list.Count);
for i := 0 to level3ooe.I16_list.Count-1
do ASSERT( level3ooe.I16_list[i] = correct.I16_list[i]);
ASSERT( level3ooe.I64_list.Count = correct.I64_list.Count);
for i := 0 to level3ooe.I64_list.Count-1
do ASSERT( level3ooe.I64_list[i] = correct.I64_list[i]);
end;
end;
finally
stream.Free;
end;
end;
procedure TTestSerializer.RunTests;
begin
try
Test_Serializer_Deserializer;
except
on e:Exception do begin
Writeln( e.Message);
Write('Hit ENTER to close ... '); Readln;
end;
end;
end;
class function TTestSerializer.Serialize(const input : IBase; const factory : IProtocolFactory) : TBytes;
var serial : TSerializer;
begin
serial := TSerializer.Create( factory);
try
result := serial.Serialize( input);
finally
serial.Free;
end;
end;
class procedure TTestSerializer.Serialize(const input : IBase; const factory : IProtocolFactory; const aStream : TStream);
var serial : TSerializer;
begin
serial := TSerializer.Create( factory);
try
serial.Serialize( input, aStream);
finally
serial.Free;
end;
end;
class procedure TTestSerializer.Deserialize( const input : TBytes; const target : IBase; const factory : IProtocolFactory);
var serial : TDeserializer;
begin
serial := TDeserializer.Create( factory);
try
serial.Deserialize( input, target);
finally
serial.Free;
end;
end;
class procedure TTestSerializer.Deserialize( const input : TStream; const target : IBase; const factory : IProtocolFactory);
var serial : TDeserializer;
begin
serial := TDeserializer.Create( factory);
try
serial.Deserialize( input, target);
finally
serial.Free;
end;
end;
var test : TTestSerializer;
begin
test := TTestSerializer.Create;
try
test.RunTests;
finally
test.Free;
end;
end.

View file

@ -0,0 +1,73 @@
(*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*)
program server;
{$APPTYPE CONSOLE}
uses
SysUtils,
TestServer in 'TestServer.pas',
TestServerEvents in 'TestServerEvents.pas',
Thrift.Test, // in gen-delphi folder
Thrift in '..\src\Thrift.pas',
Thrift.Transport in '..\src\Thrift.Transport.pas',
Thrift.Socket in '..\src\Thrift.Socket.pas',
Thrift.Transport.Pipes in '..\src\Thrift.Transport.Pipes.pas',
Thrift.Protocol in '..\src\Thrift.Protocol.pas',
Thrift.Protocol.JSON in '..\src\Thrift.Protocol.JSON.pas',
Thrift.Protocol.Compact in '..\src\Thrift.Protocol.Compact.pas',
Thrift.Protocol.Multiplex in '..\src\Thrift.Protocol.Multiplex.pas',
Thrift.Processor.Multiplex in '..\src\Thrift.Processor.Multiplex.pas',
Thrift.Collections in '..\src\Thrift.Collections.pas',
Thrift.Server in '..\src\Thrift.Server.pas',
Thrift.Console in '..\src\Thrift.Console.pas',
Thrift.TypeRegistry in '..\src\Thrift.TypeRegistry.pas',
Thrift.Utils in '..\src\Thrift.Utils.pas',
Thrift.Stream in '..\src\Thrift.Stream.pas';
var
nParamCount : Integer;
args : array of string;
i : Integer;
arg : string;
begin
try
Writeln( 'Delphi TestServer '+Thrift.Version);
nParamCount := ParamCount;
SetLength( args, nParamCount);
for i := 1 to nParamCount do begin
arg := ParamStr( i );
args[i-1] := arg;
end;
TTestServer.Execute( args );
except
on E: EAbort do begin
ExitCode := $FF;
end;
on E: Exception do begin
Writeln(E.ClassName, ': ', E.Message);
ExitCode := $FF;
end;
end;
end.

View file

@ -0,0 +1,11 @@
These two projects belong together. Both programs
simulate server and client for different versions
of the same protocol.
The intention of this test is to ensure fully
working compatibility features of the Delphi Thrift
implementation.
The expected test result is, that no errors occur
with both programs, regardless in which order they
might be started.

View file

@ -0,0 +1,45 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
// version 1 of the interface
namespace * Skiptest.One
const i32 SKIPTESTSERVICE_VERSION = 1
struct Pong {
1 : optional i32 version1
}
struct Ping {
1 : optional i32 version1
}
exception PongFailed {
222 : optional i32 pongErrorCode
}
service SkipTestService {
void PingPong( 1: Ping pong) throws (444: PongFailed pof);
}
// EOF

View file

@ -0,0 +1,69 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
// version 2 of the interface
namespace * Skiptest.Two
const i32 SKIPTESTSERVICE_VERSION = 2
struct Pong {
1 : optional i32 version1
2 : optional i16 version2
}
struct Ping {
1 : optional i32 version1
10 : optional bool boolVal
11 : optional byte byteVal
12 : optional double dbVal
13 : optional i16 i16Val
14 : optional i32 i32Val
15 : optional i64 i64Val
16 : optional string strVal
17 : optional Pong structVal
18 : optional map< list< Pong>, set< string>> mapVal
}
exception PingFailed {
1 : optional i32 pingErrorCode
}
exception PongFailed {
222 : optional i32 pongErrorCode
10 : optional bool boolVal
11 : optional byte byteVal
12 : optional double dbVal
13 : optional i16 i16Val
14 : optional i32 i32Val
15 : optional i64 i64Val
16 : optional string strVal
17 : optional Pong structVal
18 : optional map< list< Pong>, set< string>> mapVal
}
service SkipTestService {
Ping PingPong( 1: Ping ping, 3: Pong pong) throws (1: PingFailed pif, 444: PongFailed pof);
}
// EOF

View file

@ -0,0 +1,201 @@
(*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*)
program skiptest_version1;
{$APPTYPE CONSOLE}
uses
Classes, Windows, SysUtils,
Skiptest.One,
Thrift in '..\..\src\Thrift.pas',
Thrift.Socket in '..\..\src\Thrift.Socket.pas',
Thrift.Transport in '..\..\src\Thrift.Transport.pas',
Thrift.Protocol in '..\..\src\Thrift.Protocol.pas',
Thrift.Protocol.JSON in '..\..\src\Thrift.Protocol.JSON.pas',
Thrift.Collections in '..\..\src\Thrift.Collections.pas',
Thrift.Server in '..\..\src\Thrift.Server.pas',
Thrift.Console in '..\..\src\Thrift.Console.pas',
Thrift.Utils in '..\..\src\Thrift.Utils.pas',
Thrift.TypeRegistry in '..\..\src\Thrift.TypeRegistry.pas',
Thrift.Stream in '..\..\src\Thrift.Stream.pas';
const
REQUEST_EXT = '.request';
RESPONSE_EXT = '.response';
function CreatePing : IPing;
begin
result := TPingImpl.Create;
result.Version1 := Skiptest.One.TConstants.SKIPTESTSERVICE_VERSION;
end;
type
TDummyServer = class( TInterfacedObject, TSkipTestService.Iface)
protected
// TSkipTestService.Iface
procedure PingPong(const ping: IPing);
end;
procedure TDummyServer.PingPong(const ping: IPing);
// TSkipTestService.Iface
begin
Writeln('- performing request from version '+IntToStr(ping.Version1)+' client');
end;
function CreateProtocol( protfact : IProtocolFactory; stm : TStream; aForInput : Boolean) : IProtocol;
var adapt : IThriftStream;
trans : ITransport;
begin
adapt := TThriftStreamAdapterDelphi.Create( stm, FALSE);
if aForInput
then trans := TStreamTransportImpl.Create( adapt, nil)
else trans := TStreamTransportImpl.Create( nil, adapt);
result := protfact.GetProtocol( trans);
end;
procedure CreateRequest( protfact : IProtocolFactory; fname : string);
var stm : TFileStream;
ping : IPing;
proto : IProtocol;
client : TSkipTestService.TClient; // we need access to send/recv_pingpong()
cliRef : IUnknown; // holds the refcount
begin
Writeln('- creating new request');
stm := TFileStream.Create( fname+REQUEST_EXT+'.tmp', fmCreate);
try
ping := CreatePing;
// save request data
proto := CreateProtocol( protfact, stm, FALSE);
client := TSkipTestService.TClient.Create( nil, proto);
cliRef := client as IUnknown;
client.send_PingPong( ping);
finally
client := nil; // not Free!
cliRef := nil;
stm.Free;
if client = nil then {warning suppressed};
end;
DeleteFile( fname+REQUEST_EXT);
RenameFile( fname+REQUEST_EXT+'.tmp', fname+REQUEST_EXT);
end;
procedure ReadResponse( protfact : IProtocolFactory; fname : string);
var stm : TFileStream;
proto : IProtocol;
client : TSkipTestService.TClient; // we need access to send/recv_pingpong()
cliRef : IUnknown; // holds the refcount
begin
Writeln('- reading response');
stm := TFileStream.Create( fname+RESPONSE_EXT, fmOpenRead);
try
// save request data
proto := CreateProtocol( protfact, stm, TRUE);
client := TSkipTestService.TClient.Create( proto, nil);
cliRef := client as IUnknown;
client.recv_PingPong;
finally
client := nil; // not Free!
cliRef := nil;
stm.Free;
if client = nil then {warning suppressed};
end;
end;
procedure ProcessFile( protfact : IProtocolFactory; fname : string);
var stmIn, stmOut : TFileStream;
protIn, protOut : IProtocol;
server : IProcessor;
begin
Writeln('- processing request');
stmOut := nil;
stmIn := TFileStream.Create( fname+REQUEST_EXT, fmOpenRead);
try
stmOut := TFileStream.Create( fname+RESPONSE_EXT+'.tmp', fmCreate);
// process request and write response data
protIn := CreateProtocol( protfact, stmIn, TRUE);
protOut := CreateProtocol( protfact, stmOut, FALSE);
server := TSkipTestService.TProcessorImpl.Create( TDummyServer.Create);
server.Process( protIn, protOut);
finally
server := nil; // not Free!
stmIn.Free;
stmOut.Free;
if server = nil then {warning suppressed};
end;
DeleteFile( fname+RESPONSE_EXT);
RenameFile( fname+RESPONSE_EXT+'.tmp', fname+RESPONSE_EXT);
end;
procedure Test( protfact : IProtocolFactory; fname : string);
begin
// try to read an existing request
if FileExists( fname + REQUEST_EXT) then begin
ProcessFile( protfact, fname);
ReadResponse( protfact, fname);
end;
// create a new request and try to process
CreateRequest( protfact, fname);
ProcessFile( protfact, fname);
ReadResponse( protfact, fname);
end;
const
FILE_BINARY = 'pingpong.bin';
FILE_JSON = 'pingpong.json';
begin
try
Writeln( 'Delphi SkipTest '+IntToStr(TConstants.SKIPTESTSERVICE_VERSION)+' using '+Thrift.Version);
Writeln;
Writeln('Binary protocol');
Test( TBinaryProtocolImpl.TFactory.Create, FILE_BINARY);
Writeln;
Writeln('JSON protocol');
Test( TJSONProtocolImpl.TFactory.Create, FILE_JSON);
Writeln;
Writeln('Test completed without errors.');
Writeln;
Write('Press ENTER to close ...'); Readln;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.

View file

@ -0,0 +1,228 @@
(*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*)
program skiptest_version2;
{$APPTYPE CONSOLE}
uses
Classes, Windows, SysUtils,
Skiptest.Two,
Thrift in '..\..\src\Thrift.pas',
Thrift.Socket in '..\..\src\Thrift.Socket.pas',
Thrift.Transport in '..\..\src\Thrift.Transport.pas',
Thrift.Protocol in '..\..\src\Thrift.Protocol.pas',
Thrift.Protocol.JSON in '..\..\src\Thrift.Protocol.JSON.pas',
Thrift.Collections in '..\..\src\Thrift.Collections.pas',
Thrift.Server in '..\..\src\Thrift.Server.pas',
Thrift.Console in '..\..\src\Thrift.Console.pas',
Thrift.Utils in '..\..\src\Thrift.Utils.pas',
Thrift.TypeRegistry in '..\..\src\Thrift.TypeRegistry.pas',
Thrift.Stream in '..\..\src\Thrift.Stream.pas';
const
REQUEST_EXT = '.request';
RESPONSE_EXT = '.response';
function CreatePing : IPing;
var list : IThriftList<IPong>;
set_ : IHashSet<string>;
begin
result := TPingImpl.Create;
result.Version1 := Skiptest.Two.TConstants.SKIPTESTSERVICE_VERSION;
result.BoolVal := TRUE;
result.ByteVal := 2;
result.DbVal := 3;
result.I16Val := 4;
result.I32Val := 5;
result.I64Val := 6;
result.StrVal := 'seven';
result.StructVal := TPongImpl.Create;
result.StructVal.Version1 := -1;
result.StructVal.Version2 := -2;
list := TThriftListImpl<IPong>.Create;
list.Add( result.StructVal);
list.Add( result.StructVal);
set_ := THashSetImpl<string>.Create;
set_.Add( 'one');
set_.Add( 'uno');
set_.Add( 'eins');
set_.Add( 'een');
result.MapVal := TThriftDictionaryImpl< IThriftList<IPong>, IHashSet<string>>.Create;
result.MapVal.Add( list, set_);
end;
type
TDummyServer = class( TInterfacedObject, TSkipTestService.Iface)
protected
// TSkipTestService.Iface
function PingPong(const ping: IPing; const pong: IPong): IPing;
end;
function TDummyServer.PingPong(const ping: IPing; const pong: IPong): IPing;
// TSkipTestService.Iface
begin
Writeln('- performing request from version '+IntToStr(ping.Version1)+' client');
result := CreatePing;
end;
function CreateProtocol( protfact : IProtocolFactory; stm : TStream; aForInput : Boolean) : IProtocol;
var adapt : IThriftStream;
trans : ITransport;
begin
adapt := TThriftStreamAdapterDelphi.Create( stm, FALSE);
if aForInput
then trans := TStreamTransportImpl.Create( adapt, nil)
else trans := TStreamTransportImpl.Create( nil, adapt);
result := protfact.GetProtocol( trans);
end;
procedure CreateRequest( protfact : IProtocolFactory; fname : string);
var stm : TFileStream;
ping : IPing;
proto : IProtocol;
client : TSkipTestService.TClient; // we need access to send/recv_pingpong()
cliRef : IUnknown; // holds the refcount
begin
Writeln('- creating new request');
stm := TFileStream.Create( fname+REQUEST_EXT+'.tmp', fmCreate);
try
ping := CreatePing;
// save request data
proto := CreateProtocol( protfact, stm, FALSE);
client := TSkipTestService.TClient.Create( nil, proto);
cliRef := client as IUnknown;
client.send_PingPong( ping, ping.StructVal);
finally
client := nil; // not Free!
cliRef := nil;
stm.Free;
if client = nil then {warning suppressed};
end;
DeleteFile( fname+REQUEST_EXT);
RenameFile( fname+REQUEST_EXT+'.tmp', fname+REQUEST_EXT);
end;
procedure ReadResponse( protfact : IProtocolFactory; fname : string);
var stm : TFileStream;
ping : IPing;
proto : IProtocol;
client : TSkipTestService.TClient; // we need access to send/recv_pingpong()
cliRef : IUnknown; // holds the refcount
begin
Writeln('- reading response');
stm := TFileStream.Create( fname+RESPONSE_EXT, fmOpenRead);
try
// save request data
proto := CreateProtocol( protfact, stm, TRUE);
client := TSkipTestService.TClient.Create( proto, nil);
cliRef := client as IUnknown;
ping := client.recv_PingPong;
finally
client := nil; // not Free!
cliRef := nil;
stm.Free;
if client = nil then {warning suppressed};
end;
end;
procedure ProcessFile( protfact : IProtocolFactory; fname : string);
var stmIn, stmOut : TFileStream;
protIn, protOut : IProtocol;
server : IProcessor;
begin
Writeln('- processing request');
stmOut := nil;
stmIn := TFileStream.Create( fname+REQUEST_EXT, fmOpenRead);
try
stmOut := TFileStream.Create( fname+RESPONSE_EXT+'.tmp', fmCreate);
// process request and write response data
protIn := CreateProtocol( protfact, stmIn, TRUE);
protOut := CreateProtocol( protfact, stmOut, FALSE);
server := TSkipTestService.TProcessorImpl.Create( TDummyServer.Create);
server.Process( protIn, protOut);
finally
server := nil; // not Free!
stmIn.Free;
stmOut.Free;
if server = nil then {warning suppressed};
end;
DeleteFile( fname+RESPONSE_EXT);
RenameFile( fname+RESPONSE_EXT+'.tmp', fname+RESPONSE_EXT);
end;
procedure Test( protfact : IProtocolFactory; fname : string);
begin
// try to read an existing request
if FileExists( fname + REQUEST_EXT) then begin
ProcessFile( protfact, fname);
ReadResponse( protfact, fname);
end;
// create a new request and try to process
CreateRequest( protfact, fname);
ProcessFile( protfact, fname);
ReadResponse( protfact, fname);
end;
const
FILE_BINARY = 'pingpong.bin';
FILE_JSON = 'pingpong.json';
begin
try
Writeln( 'Delphi SkipTest '+IntToStr(TConstants.SKIPTESTSERVICE_VERSION)+' using '+Thrift.Version);
Writeln;
Writeln('Binary protocol');
Test( TBinaryProtocolImpl.TFactory.Create, FILE_BINARY);
Writeln;
Writeln('JSON protocol');
Test( TJSONProtocolImpl.TFactory.Create, FILE_JSON);
Writeln;
Writeln('Test completed without errors.');
Writeln;
Write('Press ENTER to close ...'); Readln;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.

View file

@ -0,0 +1,90 @@
(*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*)
program TestTypeRegistry;
{$APPTYPE CONSOLE}
uses
Classes, Windows, SysUtils, Generics.Collections, TypInfo,
Thrift in '..\..\src\Thrift.pas',
Thrift.Transport in '..\..\src\Thrift.Transport.pas',
Thrift.Socket in '..\..\src\Thrift.Socket.pas',
Thrift.Protocol in '..\..\src\Thrift.Protocol.pas',
Thrift.Protocol.JSON in '..\..\src\Thrift.Protocol.JSON.pas',
Thrift.Collections in '..\..\src\Thrift.Collections.pas',
Thrift.Server in '..\..\src\Thrift.Server.pas',
Thrift.Console in '..\..\src\Thrift.Console.pas',
Thrift.Utils in '..\..\src\Thrift.Utils.pas',
Thrift.Serializer in '..\..\src\Thrift.Serializer.pas',
Thrift.Stream in '..\..\src\Thrift.Stream.pas',
Thrift.TypeRegistry in '..\..\src\Thrift.TypeRegistry.pas',
DebugProtoTest;
type
Tester<T : IInterface> = class
public
class procedure Test;
end;
class procedure Tester<T>.Test;
var instance : T;
name : string;
begin
instance := TypeRegistry.Construct<T>;
name := GetTypeName(TypeInfo(T));
if instance <> nil
then Writeln( name, ' = ok')
else begin
Writeln( name, ' = failed');
raise Exception.Create( 'Test with '+name+' failed!');
end;
end;
begin
Writeln('Testing ...');
Tester<IDoubles>.Test;
Tester<IOneOfEach>.Test;
Tester<IBonk>.Test;
Tester<INesting>.Test;
Tester<IHolyMoley>.Test;
Tester<IBackwards>.Test;
Tester<IEmpty>.Test;
Tester<IWrapper>.Test;
Tester<IRandomStuff>.Test;
Tester<IBase64>.Test;
Tester<ICompactProtoTestStruct>.Test;
Tester<ISingleMapTestStruct>.Test;
Tester<IBlowUp>.Test;
Tester<IReverseOrderStruct>.Test;
Tester<IStructWithSomeEnum>.Test;
Tester<ITestUnion>.Test;
Tester<ITestUnionMinusStringField>.Test;
Tester<IComparableUnion>.Test;
Tester<IStructWithAUnion>.Test;
Tester<IPrimitiveThenStruct>.Test;
Tester<IStructWithASomemap>.Test;
Tester<IBigFieldIdStruct>.Test;
Tester<IBreaksRubyCompactProtocol>.Test;
Tester<ITupleProtocolTestStruct>.Test;
Writeln('Completed.');
end.