THRIFT-5009 Serializer implemtation lacks support for layered transports
Client: Delphi
Patch: Jens Geyer
diff --git a/lib/delphi/test/serializer/TestSerializer.Tests.pas b/lib/delphi/test/serializer/TestSerializer.Tests.pas
new file mode 100644
index 0000000..ec8d86d
--- /dev/null
+++ b/lib/delphi/test/serializer/TestSerializer.Tests.pas
@@ -0,0 +1,329 @@
+unit TestSerializer.Tests;
+(*
+ * 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.
+ *)
+
+interface
+
+uses
+ Classes,
+ Windows,
+ SysUtils,
+ Generics.Collections,
+ Thrift,
+ Thrift.Exception,
+ Thrift.Socket,
+ Thrift.Transport,
+ Thrift.Protocol,
+ Thrift.Protocol.JSON,
+ Thrift.Protocol.Compact,
+ Thrift.Collections,
+ Thrift.Server,
+ Thrift.Utils,
+ Thrift.Serializer,
+ Thrift.Stream,
+ Thrift.WinHTTP,
+ Thrift.TypeRegistry,
+ System_,
+ DebugProtoTest,
+ TestSerializer.Data;
+
+
+type
+ TFactoryPair = record
+ prot : IProtocolFactory;
+ trans : ITransportFactory;
+ end;
+
+ TTestSerializer = class //extends TestCase {
+ private type
+ TMethod = (
+ mt_Bytes,
+ mt_Stream
+ );
+
+ private
+ FProtocols : TList< TFactoryPair>;
+ procedure AddFactoryCombination( const aProto : IProtocolFactory; const aTrans : ITransportFactory);
+ class function UserFriendlyName( const factory : TFactoryPair) : string; overload;
+ class function UserFriendlyName( const method : TMethod) : string; overload;
+
+ class function Serialize(const input : IBase; const factory : TFactoryPair) : TBytes; overload;
+ class procedure Serialize(const input : IBase; const factory : TFactoryPair; const aStream : TStream); overload;
+
+ class procedure Deserialize( const input : TBytes; const target : IBase; const factory : TFactoryPair); overload;
+ class procedure Deserialize( const input : TStream; const target : IBase; const factory : TFactoryPair); overload;
+
+ procedure Test_Serializer_Deserializer;
+ procedure Test_OneOfEach( const method : TMethod; const factory : TFactoryPair; const stream : TFileStream);
+ procedure Test_CompactStruct( const method : TMethod; const factory : TFactoryPair; const stream : TFileStream);
+
+ public
+ constructor Create;
+ destructor Destroy; override;
+
+ procedure RunTests;
+ end;
+
+
+implementation
+
+
+{ TTestSerializer }
+
+constructor TTestSerializer.Create;
+begin
+ inherited Create;
+ FProtocols := TList< TFactoryPair>.Create;
+
+ AddFactoryCombination( TBinaryProtocolImpl.TFactory.Create, nil);
+ AddFactoryCombination( TCompactProtocolImpl.TFactory.Create, nil);
+ AddFactoryCombination( TJSONProtocolImpl.TFactory.Create, nil);
+
+ AddFactoryCombination( TBinaryProtocolImpl.TFactory.Create, TFramedTransportImpl.TFactory.Create);
+ AddFactoryCombination( TCompactProtocolImpl.TFactory.Create, TFramedTransportImpl.TFactory.Create);
+ AddFactoryCombination( TJSONProtocolImpl.TFactory.Create, TFramedTransportImpl.TFactory.Create);
+
+ AddFactoryCombination( TBinaryProtocolImpl.TFactory.Create, TBufferedTransportImpl.TFactory.Create);
+ AddFactoryCombination( TCompactProtocolImpl.TFactory.Create, TBufferedTransportImpl.TFactory.Create);
+ AddFactoryCombination( TJSONProtocolImpl.TFactory.Create, TBufferedTransportImpl.TFactory.Create);
+end;
+
+
+destructor TTestSerializer.Destroy;
+begin
+ try
+ FreeAndNil( FProtocols);
+ finally
+ inherited Destroy;
+ end;
+end;
+
+
+procedure TTestSerializer.AddFactoryCombination( const aProto : IProtocolFactory; const aTrans : ITransportFactory);
+var rec : TFactoryPair;
+begin
+ rec.prot := aProto;
+ rec.trans := aTrans;
+ FProtocols.Add( rec);
+end;
+
+
+procedure TTestSerializer.Test_OneOfEach( const method : TMethod; const factory : TFactoryPair; const stream : TFileStream);
+var tested, correct : IOneOfEach;
+ bytes : TBytes;
+ i : Integer;
+begin
+ // write
+ tested := Fixtures.CreateOneOfEach;
+ case method of
+ mt_Bytes: bytes := Serialize( tested, factory);
+ mt_Stream: begin
+ stream.Size := 0;
+ Serialize( tested, factory, stream);
+ end
+ else
+ ASSERT( FALSE);
+ end;
+
+ // init + read
+ tested := TOneOfEachImpl.Create;
+ case method of
+ mt_Bytes: Deserialize( bytes, tested, factory);
+ mt_Stream: begin
+ stream.Position := 0;
+ Deserialize( stream, tested, factory);
+ end
+ else
+ ASSERT( FALSE);
+ end;
+
+ // check
+ correct := Fixtures.CreateOneOfEach;
+ ASSERT( tested.Im_true = correct.Im_true);
+ ASSERT( tested.Im_false = correct.Im_false);
+ ASSERT( tested.A_bite = correct.A_bite);
+ ASSERT( tested.Integer16 = correct.Integer16);
+ ASSERT( tested.Integer32 = correct.Integer32);
+ ASSERT( tested.Integer64 = correct.Integer64);
+ ASSERT( Abs( tested.Double_precision - correct.Double_precision) < 1E-12);
+ ASSERT( tested.Some_characters = correct.Some_characters);
+ ASSERT( tested.Zomg_unicode = correct.Zomg_unicode);
+ ASSERT( tested.What_who = correct.What_who);
+
+ ASSERT( Length(tested.Base64) = Length(correct.Base64));
+ ASSERT( CompareMem( @tested.Base64[0], @correct.Base64[0], Length(correct.Base64)));
+
+ ASSERT( tested.Byte_list.Count = correct.Byte_list.Count);
+ for i := 0 to tested.Byte_list.Count-1
+ do ASSERT( tested.Byte_list[i] = correct.Byte_list[i]);
+
+ ASSERT( tested.I16_list.Count = correct.I16_list.Count);
+ for i := 0 to tested.I16_list.Count-1
+ do ASSERT( tested.I16_list[i] = correct.I16_list[i]);
+
+ ASSERT( tested.I64_list.Count = correct.I64_list.Count);
+ for i := 0 to tested.I64_list.Count-1
+ do ASSERT( tested.I64_list[i] = correct.I64_list[i]);
+end;
+
+
+procedure TTestSerializer.Test_CompactStruct( const method : TMethod; const factory : TFactoryPair; const stream : TFileStream);
+var tested, correct : ICompactProtoTestStruct;
+ bytes : TBytes;
+begin
+ // write
+ tested := Fixtures.CreateCompactProtoTestStruct;
+ case method of
+ mt_Bytes: bytes := Serialize( tested, factory);
+ mt_Stream: begin
+ stream.Size := 0;
+ Serialize( tested, factory, stream);
+ end
+ else
+ ASSERT( FALSE);
+ end;
+
+ // init + read
+ correct := TCompactProtoTestStructImpl.Create;
+ case method of
+ mt_Bytes: Deserialize( bytes, tested, factory);
+ mt_Stream: begin
+ stream.Position := 0;
+ Deserialize( stream, tested, factory);
+ end
+ else
+ ASSERT( FALSE);
+ end;
+
+ // check
+ correct := Fixtures.CreateCompactProtoTestStruct;
+ ASSERT( correct.Field500 = tested.Field500);
+ ASSERT( correct.Field5000 = tested.Field5000);
+ ASSERT( correct.Field20000 = tested.Field20000);
+end;
+
+
+procedure TTestSerializer.Test_Serializer_Deserializer;
+var factory : TFactoryPair;
+ stream : TFileStream;
+ method : TMethod;
+begin
+ stream := TFileStream.Create( 'TestSerializer.dat', fmCreate);
+ try
+ for method in [Low(TMethod)..High(TMethod)] do begin
+ Writeln( UserFriendlyName(method));
+
+ for factory in FProtocols do begin
+ Writeln('- '+UserFriendlyName(factory));
+
+ Test_OneOfEach( method, factory, stream);
+ Test_CompactStruct( method, factory, stream);
+ end;
+
+ Writeln;
+ end;
+
+ finally
+ stream.Free;
+ end;
+end;
+
+
+class function TTestSerializer.UserFriendlyName( const factory : TFactoryPair) : string;
+begin
+ result := Copy( (factory.prot as TObject).ClassName, 2, MAXINT);
+
+ if factory.trans <> nil
+ then result := Copy( (factory.trans as TObject).ClassName, 2, MAXINT) +' '+ result;
+
+ result := StringReplace( result, 'Impl', '', [rfReplaceAll]);
+ result := StringReplace( result, 'Transport.TFactory', '', [rfReplaceAll]);
+ result := StringReplace( result, 'Protocol.TFactory', '', [rfReplaceAll]);
+end;
+
+
+class function TTestSerializer.UserFriendlyName( const method : TMethod) : string;
+begin
+ result := EnumUtils<TMethod>.ToString(Ord(method));
+ result := StringReplace( result, 'mt_', '', [rfReplaceAll]);
+end;
+
+
+procedure TTestSerializer.RunTests;
+begin
+ try
+ Test_Serializer_Deserializer;
+ except
+ on e:Exception do begin
+ Writeln( e.ClassName+': '+ e.Message);
+ Write('Hit ENTER to close ... '); Readln;
+ end;
+ end;
+end;
+
+
+class function TTestSerializer.Serialize(const input : IBase; const factory : TFactoryPair) : TBytes;
+var serial : TSerializer;
+begin
+ serial := TSerializer.Create( factory.prot, factory.trans);
+ try
+ result := serial.Serialize( input);
+ finally
+ serial.Free;
+ end;
+end;
+
+
+class procedure TTestSerializer.Serialize(const input : IBase; const factory : TFactoryPair; const aStream : TStream);
+var serial : TSerializer;
+begin
+ serial := TSerializer.Create( factory.prot, factory.trans);
+ try
+ serial.Serialize( input, aStream);
+ finally
+ serial.Free;
+ end;
+end;
+
+
+class procedure TTestSerializer.Deserialize( const input : TBytes; const target : IBase; const factory : TFactoryPair);
+var serial : TDeserializer;
+begin
+ serial := TDeserializer.Create( factory.prot, factory.trans);
+ try
+ serial.Deserialize( input, target);
+ finally
+ serial.Free;
+ end;
+end;
+
+
+class procedure TTestSerializer.Deserialize( const input : TStream; const target : IBase; const factory : TFactoryPair);
+var serial : TDeserializer;
+begin
+ serial := TDeserializer.Create( factory.prot, factory.trans);
+ try
+ serial.Deserialize( input, target);
+ finally
+ serial.Free;
+ end;
+end;
+
+
+end.
diff --git a/lib/delphi/test/serializer/TestSerializer.dpr b/lib/delphi/test/serializer/TestSerializer.dpr
index 39752cf..bb4cc89 100644
--- a/lib/delphi/test/serializer/TestSerializer.dpr
+++ b/lib/delphi/test/serializer/TestSerializer.dpr
@@ -42,235 +42,9 @@
Thrift.TypeRegistry in '..\..\src\Thrift.TypeRegistry.pas',
System_,
DebugProtoTest,
+ TestSerializer.Tests,
TestSerializer.Data;
-type
- TTestSerializer = class //extends TestCase {
- private type
- TMethod = (
- mt_Bytes,
- mt_Stream
- );
-
- 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;
- procedure Test_OneOfEach( const method : TMethod; const factory : IProtocolFactory; const stream : TFileStream);
- procedure Test_CompactStruct( const method : TMethod; const factory : IProtocolFactory; const stream : TFileStream);
-
- 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;
-
-
-procedure TTestSerializer.Test_OneOfEach( const method : TMethod; const factory : IProtocolFactory; const stream : TFileStream);
-var tested, correct : IOneOfEach;
- bytes : TBytes;
- i : Integer;
-begin
- // write
- tested := Fixtures.CreateOneOfEach;
- case method of
- mt_Bytes: bytes := Serialize( tested, factory);
- mt_Stream: begin
- stream.Size := 0;
- Serialize( tested, factory, stream);
- end
- else
- ASSERT( FALSE);
- end;
-
- // init + read
- tested := TOneOfEachImpl.Create;
- case method of
- mt_Bytes: Deserialize( bytes, tested, factory);
- mt_Stream: begin
- stream.Position := 0;
- Deserialize( stream, tested, factory);
- end
- else
- ASSERT( FALSE);
- end;
-
- // check
- correct := Fixtures.CreateOneOfEach;
- ASSERT( tested.Im_true = correct.Im_true);
- ASSERT( tested.Im_false = correct.Im_false);
- ASSERT( tested.A_bite = correct.A_bite);
- ASSERT( tested.Integer16 = correct.Integer16);
- ASSERT( tested.Integer32 = correct.Integer32);
- ASSERT( tested.Integer64 = correct.Integer64);
- ASSERT( Abs( tested.Double_precision - correct.Double_precision) < 1E-12);
- ASSERT( tested.Some_characters = correct.Some_characters);
- ASSERT( tested.Zomg_unicode = correct.Zomg_unicode);
- ASSERT( tested.What_who = correct.What_who);
-
- ASSERT( Length(tested.Base64) = Length(correct.Base64));
- ASSERT( CompareMem( @tested.Base64[0], @correct.Base64[0], Length(correct.Base64)));
-
- ASSERT( tested.Byte_list.Count = correct.Byte_list.Count);
- for i := 0 to tested.Byte_list.Count-1
- do ASSERT( tested.Byte_list[i] = correct.Byte_list[i]);
-
- ASSERT( tested.I16_list.Count = correct.I16_list.Count);
- for i := 0 to tested.I16_list.Count-1
- do ASSERT( tested.I16_list[i] = correct.I16_list[i]);
-
- ASSERT( tested.I64_list.Count = correct.I64_list.Count);
- for i := 0 to tested.I64_list.Count-1
- do ASSERT( tested.I64_list[i] = correct.I64_list[i]);
-end;
-
-
-procedure TTestSerializer.Test_CompactStruct( const method : TMethod; const factory : IProtocolFactory; const stream : TFileStream);
-var tested, correct : ICompactProtoTestStruct;
- bytes : TBytes;
-begin
- // write
- tested := Fixtures.CreateCompactProtoTestStruct;
- case method of
- mt_Bytes: bytes := Serialize( tested, factory);
- mt_Stream: begin
- stream.Size := 0;
- Serialize( tested, factory, stream);
- end
- else
- ASSERT( FALSE);
- end;
-
- // init + read
- correct := TCompactProtoTestStructImpl.Create;
- case method of
- mt_Bytes: Deserialize( bytes, tested, factory);
- mt_Stream: begin
- stream.Position := 0;
- Deserialize( stream, tested, factory);
- end
- else
- ASSERT( FALSE);
- end;
-
- // check
- correct := Fixtures.CreateCompactProtoTestStruct;
- ASSERT( correct.Field500 = tested.Field500);
- ASSERT( correct.Field5000 = tested.Field5000);
- ASSERT( correct.Field20000 = tested.Field20000);
-end;
-
-
-procedure TTestSerializer.Test_Serializer_Deserializer;
-var factory : IProtocolFactory;
- stream : TFileStream;
- method : TMethod;
-begin
- stream := TFileStream.Create( 'TestSerializer.dat', fmCreate);
- try
-
- for method in [Low(TMethod)..High(TMethod)] do begin
- for factory in FProtocols do begin
-
- Test_OneOfEach( method, factory, stream);
- Test_CompactStruct( method, factory, stream);
- 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