DateUtils,\r
Generics.Collections,\r
TestConstants,\r
+ Thrift,\r
Thrift.Protocol.JSON,\r
Thrift.Protocol,\r
Thrift.Transport,\r
FNumIteration : Integer;\r
FConsole : TThreadConsole;\r
\r
- FErrors, FSuccesses : Integer;\r
+ // test reporting, will be refactored out into separate class later\r
+ FTestGroup : string;\r
+ FSuccesses : Integer;\r
+ FErrors : TStringList;\r
+ procedure StartTestGroup( const aGroup : string);\r
procedure Expect( aTestResult : Boolean; const aTestInfo : string);\r
+ procedure ReportResults;\r
\r
procedure ClientTest;\r
procedure JSONProtocolReadWriteTest;\r
\r
implementation\r
\r
+function BoolToString( b : Boolean) : string;\r
+// overrides global BoolToString()\r
+begin\r
+ if b\r
+ then result := 'true'\r
+ else result := 'false';\r
+end;\r
+\r
\r
{ TTestClient }\r
\r
ret : TNumberz;\r
uid : Int64;\r
mm : IThriftDictionary<Integer, IThriftDictionary<Integer, Integer>>;\r
+ pos : IThriftDictionary<Integer, Integer>;\r
+ neg : IThriftDictionary<Integer, Integer>;\r
m2 : IThriftDictionary<Integer, Integer>;\r
k2 : Integer;\r
insane : IInsanity;\r
arg0 : ShortInt;\r
arg1 : Integer;\r
arg2 : Int64;\r
- multiDict : IThriftDictionary<SmallInt, string>;\r
+ arg3 : IThriftDictionary<SmallInt, string>;\r
arg4 : TNumberz;\r
arg5 : Int64;\r
StartTick : Cardinal;\r
k : Integer;\r
proc : TThreadProcedure;\r
+ hello, goodbye : IXtruct;\r
+ crazy : IInsanity;\r
+ looney : IInsanity;\r
+ first_map : IThriftDictionary<TNumberz, IInsanity>;\r
+ second_map : IThriftDictionary<TNumberz, IInsanity>;\r
\r
begin\r
client := TThriftTest.TClient.Create( FProtocol);\r
end;\r
end;\r
\r
- Console.Write('testException()');\r
+ // in-depth exception test\r
+ // (1) do we get an exception at all?\r
+ // (2) do we get the right exception?\r
+ // (3) does the exception contain the expected data?\r
+ StartTestGroup( 'testException');\r
try\r
client.testException('Xception');\r
+ Expect( FALSE, 'testException(''Xception''): must trow an exception');\r
except\r
- on E: TXception do\r
- begin\r
- Console.WriteLine( ' = ' + IntToStr(E.ErrorCode) + ', ' + E.Message_ );\r
+ on e:TXception do begin\r
+ Expect( e.ErrorCode = 1001, 'error code');\r
+ Expect( e.Message_ = 'This is an Xception', 'error message');\r
+ Console.WriteLine( ' = ' + IntToStr(e.ErrorCode) + ', ' + e.Message_ );\r
end;\r
+ on e:TTransportException do Expect( FALSE, 'Unexpected : "'+e.ToString+'"');\r
+ on e:Exception do Expect( FALSE, 'Unexpected exception type "'+e.ClassName+'"');\r
end;\r
\r
- Console.Write('testVoid()');\r
+ // simple things\r
+ StartTestGroup( 'simple Thrift calls');\r
client.testVoid();\r
- Console.WriteLine(' = void');\r
+ Expect( TRUE, 'testVoid()'); // success := no exception\r
\r
- Console.Write('testString(''Test'')');\r
s := client.testString('Test');\r
- Console.WriteLine(' := ''' + s + '''');\r
+ Expect( s = 'Test', 'testString(''Test'') = "'+s+'"');\r
\r
- Console.Write('testByte(1)');\r
i8 := client.testByte(1);\r
- Console.WriteLine(' := ' + IntToStr( i8 ));\r
+ Expect( i8 = 1, 'testByte(1) = ' + IntToStr( i8 ));\r
\r
- Console.Write('testI32(-1)');\r
i32 := client.testI32(-1);\r
- Console.WriteLine(' := ' + IntToStr(i32));\r
+ Expect( i32 = -1, 'testI32(-1) = ' + IntToStr(i32));\r
\r
- Console.Write('testI64(-34359738368)');\r
+ Console.WriteLine('testI64(-34359738368)');\r
i64 := client.testI64(-34359738368);\r
- Console.WriteLine(' := ' + IntToStr( i64));\r
+ Expect( i64 = -34359738368, 'testI64(-34359738368) = ' + IntToStr( i64));\r
\r
- Console.Write('testDouble(5.325098235)');\r
+ Console.WriteLine('testDouble(5.325098235)');\r
dub := client.testDouble(5.325098235);\r
- Console.WriteLine(' := ' + FloatToStr( dub));\r
+ Expect( abs(dub-5.325098235) < 1e-14, 'testDouble(5.325098235) = ' + FloatToStr( dub));\r
\r
- Console.Write('testStruct({''Zero'', 1, -3, -5})');\r
+ // structs\r
+ StartTestGroup( 'testStruct');\r
+ Console.WriteLine('testStruct({''Zero'', 1, -3, -5})');\r
o := TXtructImpl.Create;\r
o.String_thing := 'Zero';\r
o.Byte_thing := 1;\r
o.I32_thing := -3;\r
o.I64_thing := -5;\r
i := client.testStruct(o);\r
- Console.WriteLine(' := {''' +\r
- i.String_thing + ''', ' +\r
- IntToStr( i.Byte_thing) + ', ' +\r
- IntToStr( i.I32_thing) + ', ' +\r
- IntToStr( i.I64_thing) + '}');\r
-\r
- Console.Write('testNest({1, {''Zero'', 1, -3, -5}, 5})');\r
+ Expect( i.String_thing = 'Zero', 'i.String_thing = "'+i.String_thing+'"');\r
+ Expect( i.Byte_thing = 1, 'i.Byte_thing = '+IntToStr(i.Byte_thing));\r
+ Expect( i.I32_thing = -3, 'i.I32_thing = '+IntToStr(i.I32_thing));\r
+ Expect( i.I64_thing = -5, 'i.I64_thing = '+IntToStr(i.I64_thing));\r
+ Expect( i.__isset_String_thing, 'i.__isset_String_thing = '+BoolToString(i.__isset_String_thing));\r
+ Expect( i.__isset_Byte_thing, 'i.__isset_Byte_thing = '+BoolToString(i.__isset_Byte_thing));\r
+ Expect( i.__isset_I32_thing, 'i.__isset_I32_thing = '+BoolToString(i.__isset_I32_thing));\r
+ Expect( i.__isset_I64_thing, 'i.__isset_I64_thing = '+BoolToString(i.__isset_I64_thing));\r
+\r
+ // nested structs\r
+ StartTestGroup( 'testNest');\r
+ Console.WriteLine('testNest({1, {''Zero'', 1, -3, -5}, 5})');\r
o2 := TXtruct2Impl.Create;\r
o2.Byte_thing := 1;\r
o2.Struct_thing := o;\r
o2.I32_thing := 5;\r
i2 := client.testNest(o2);\r
i := i2.Struct_thing;\r
- Console.WriteLine(' := {' + IntToStr( i2.Byte_thing) + ', {''' +\r
- i.String_thing + ''', ' +\r
- IntToStr( i.Byte_thing) + ', ' +\r
- IntToStr( i.I32_thing) + ', ' +\r
- IntToStr( i.I64_thing) + '}, ' +\r
- IntToStr( i2.I32_thing) + '}');\r
-\r
-\r
+ Expect( i.String_thing = 'Zero', 'i.String_thing = "'+i.String_thing+'"');\r
+ Expect( i.Byte_thing = 1, 'i.Byte_thing = '+IntToStr(i.Byte_thing));\r
+ Expect( i.I32_thing = -3, 'i.I32_thing = '+IntToStr(i.I32_thing));\r
+ Expect( i.I64_thing = -5, 'i.I64_thing = '+IntToStr(i.I64_thing));\r
+ Expect( i2.Byte_thing = 1, 'i2.Byte_thing = '+IntToStr(i2.Byte_thing));\r
+ Expect( i2.I32_thing = 5, 'i2.I32_thing = '+IntToStr(i2.I32_thing));\r
+ Expect( i.__isset_String_thing, 'i.__isset_String_thing = '+BoolToString(i.__isset_String_thing));\r
+ Expect( i.__isset_Byte_thing, 'i.__isset_Byte_thing = '+BoolToString(i.__isset_Byte_thing));\r
+ Expect( i.__isset_I32_thing, 'i.__isset_I32_thing = '+BoolToString(i.__isset_I32_thing));\r
+ Expect( i.__isset_I64_thing, 'i.__isset_I64_thing = '+BoolToString(i.__isset_I64_thing));\r
+ Expect( i2.__isset_Byte_thing, 'i2.__isset_Byte_thing');\r
+ Expect( i2.__isset_I32_thing, 'i2.__isset_I32_thing');\r
+\r
+ // map<type1,type2>: A map of strictly unique keys to values.\r
+ // Translates to an STL map, Java HashMap, PHP associative array, Python/Ruby dictionary, etc.\r
+ StartTestGroup( 'testMap');\r
mapout := TThriftDictionaryImpl<Integer,Integer>.Create;\r
-\r
for j := 0 to 4 do\r
begin\r
mapout.AddOrSetValue( j, j - 10);\r
first := True;\r
for key in mapout.Keys do\r
begin\r
- if first then\r
- begin\r
- first := False;\r
- end else\r
- begin\r
- Console.Write( ', ' );\r
- end;\r
+ if first\r
+ then first := False\r
+ else Console.Write( ', ' );\r
Console.Write( IntToStr( key) + ' => ' + IntToStr( mapout[key]));\r
end;\r
- Console.Write('})');\r
+ Console.WriteLine('})');\r
\r
mapin := client.testMap( mapout );\r
- Console.Write(' = {');\r
- first := True;\r
+ Expect( mapin.Count = mapout.Count, 'testMap: mapin.Count = mapout.Count');\r
+ for j := 0 to 4 do\r
+ begin\r
+ Expect( mapout.ContainsKey(j), 'testMap: mapout.ContainsKey('+IntToStr(j)+') = '+BoolToString(mapout.ContainsKey(j)));\r
+ end;\r
for key in mapin.Keys do\r
begin\r
- if first then\r
- begin\r
- first := False;\r
- end else\r
- begin\r
- Console.Write( ', ' );\r
- end;\r
- Console.Write( IntToStr( key) + ' => ' + IntToStr( mapin[key]));\r
+ Expect( mapin[key] = mapout[key], 'testMap: '+IntToStr(key) + ' => ' + IntToStr( mapin[key]));\r
+ Expect( mapin[key] = key - 10, 'testMap: mapin['+IntToStr(key)+'] = '+IntToStr( mapin[key]));\r
end;\r
- Console.WriteLine('}');\r
\r
+\r
+ // set<type>: An unordered set of unique elements.\r
+ // Translates to an STL set, Java HashSet, set in Python, etc.\r
+ // Note: PHP does not support sets, so it is treated similar to a List\r
+ StartTestGroup( 'testSet');\r
setout := THashSetImpl<Integer>.Create;\r
for j := -2 to 2 do\r
begin\r
first := True;\r
for j in setout do\r
begin\r
- if first then\r
- begin\r
- first := False;\r
- end else\r
- begin\r
- Console.Write(', ');\r
- end;\r
+ if first\r
+ then first := False\r
+ else Console.Write(', ');\r
Console.Write(IntToStr( j));\r
end;\r
- Console.Write('})');\r
-\r
- Console.Write(' = {');\r
+ Console.WriteLine('})');\r
\r
- first := True;\r
setin := client.testSet(setout);\r
- for j in setin do\r
+ Expect( setin.Count = setout.Count, 'testSet: setin.Count = setout.Count');\r
+ Expect( setin.Count = 5, 'testSet: setin.Count = '+IntToStr(setin.Count));\r
+ for j := -2 to 2 do // unordered, we can't rely on the order => test for known elements only\r
begin\r
- if first then\r
- begin\r
- first := False;\r
- end else\r
+ Expect( setin.Contains(j), 'testSet: setin.Contains('+IntToStr(j)+') => '+BoolToString(setin.Contains(j)));\r
+ end;\r
+\r
+ // list<type>: An ordered list of elements.\r
+ // Translates to an STL vector, Java ArrayList, native arrays in scripting languages, etc.\r
+ StartTestGroup( 'testList');\r
+ listout := TThriftListImpl<Integer>.Create;\r
+ listout.Add( +1);\r
+ listout.Add( -2);\r
+ listout.Add( +3);\r
+ listout.Add( -4);\r
+ listout.Add( 0);\r
+ Console.Write('testList({');\r
+ first := True;\r
+ for j in listout do\r
begin\r
- Console.Write(', ');\r
- end;\r
+ if first\r
+ then first := False\r
+ else Console.Write(', ');\r
Console.Write(IntToStr( j));\r
end;\r
- Console.WriteLine('}');\r
-\r
- Console.Write('testEnum(ONE)');\r
+ Console.WriteLine('})');\r
+\r
+ listin := client.testList(listout);\r
+ Expect( listin.Count = listout.Count, 'testList: listin.Count = listout.Count');\r
+ Expect( listin.Count = 5, 'testList: listin.Count = '+IntToStr(listin.Count));\r
+ Expect( listin[0] = +1, 'listin[0] = '+IntToStr( listin[0]));\r
+ Expect( listin[1] = -2, 'listin[1] = '+IntToStr( listin[1]));\r
+ Expect( listin[2] = +3, 'listin[2] = '+IntToStr( listin[2]));\r
+ Expect( listin[3] = -4, 'listin[3] = '+IntToStr( listin[3]));\r
+ Expect( listin[4] = 0, 'listin[4] = '+IntToStr( listin[4]));\r
+\r
+ // enums\r
ret := client.testEnum(TNumberz.ONE);\r
- Console.WriteLine(' = ' + IntToStr( Integer( ret)));\r
+ Expect( ret = TNumberz.ONE, 'testEnum(ONE) = '+IntToStr(Ord(ret)));\r
\r
- Console.Write('testEnum(TWO)');\r
ret := client.testEnum(TNumberz.TWO);\r
- Console.WriteLine(' = ' + IntToStr( Integer( ret)));\r
+ Expect( ret = TNumberz.TWO, 'testEnum(TWO) = '+IntToStr(Ord(ret)));\r
\r
- Console.Write('testEnum(THREE)');\r
ret := client.testEnum(TNumberz.THREE);\r
- Console.WriteLine(' = ' + IntToStr( Integer( ret)));\r
+ Expect( ret = TNumberz.THREE, 'testEnum(THREE) = '+IntToStr(Ord(ret)));\r
\r
- Console.Write('testEnum(FIVE)');\r
ret := client.testEnum(TNumberz.FIVE);\r
- Console.WriteLine(' = ' + IntToStr( Integer( ret)));\r
+ Expect( ret = TNumberz.FIVE, 'testEnum(FIVE) = '+IntToStr(Ord(ret)));\r
\r
- Console.Write('testEnum(EIGHT)');\r
ret := client.testEnum(TNumberz.EIGHT);\r
- Console.WriteLine(' = ' + IntToStr( Integer( ret)));\r
+ Expect( ret = TNumberz.EIGHT, 'testEnum(EIGHT) = '+IntToStr(Ord(ret)));\r
+\r
\r
- Console.Write('testTypedef(309858235082523)');\r
+ // typedef\r
uid := client.testTypedef(309858235082523);\r
- Console.WriteLine(' = ' + IntToStr( uid));\r
+ Expect( uid = 309858235082523, 'testTypedef(309858235082523) = '+IntToStr(uid));\r
+\r
\r
- Console.Write('testMapMap(1)');\r
+ // maps of maps\r
+ StartTestGroup( 'testMapMap(1)');\r
mm := client.testMapMap(1);\r
Console.Write(' = {');\r
for key in mm.Keys do\r
end;\r
Console.WriteLine('}');\r
\r
+ // verify result data\r
+ Expect( mm.Count = 2, 'mm.Count = '+IntToStr(mm.Count));\r
+ pos := mm[4];\r
+ neg := mm[-4];\r
+ for j := 1 to 4 do\r
+ begin\r
+ Expect( pos[j] = j, 'pos[j] = '+IntToStr(pos[j]));\r
+ Expect( neg[-j] = -j, 'neg[-j] = '+IntToStr(neg[-j]));\r
+ end;\r
+\r
+\r
+\r
+ // insanity\r
+ StartTestGroup( 'testInsanity');\r
insane := TInsanityImpl.Create;\r
insane.UserMap := TThriftDictionaryImpl<TNumberz, Int64>.Create;\r
insane.UserMap.AddOrSetValue( TNumberz.FIVE, 5000);\r
truck.I64_thing := 8;\r
insane.Xtructs := TThriftListImpl<IXtruct>.Create;\r
insane.Xtructs.Add( truck );\r
- Console.Write('testInsanity()');\r
whoa := client.testInsanity( insane );\r
Console.Write(' = {');\r
for key64 in whoa.Keys do\r
end;\r
Console.WriteLine('}');\r
\r
+ // verify result data\r
+ Expect( whoa.Count = 2, 'whoa.Count = '+IntToStr(whoa.Count));\r
+ //\r
+ first_map := whoa[1];\r
+ second_map := whoa[2];\r
+ Expect( first_map.Count = 2, 'first_map.Count = '+IntToStr(first_map.Count));\r
+ Expect( second_map.Count = 1, 'second_map.Count = '+IntToStr(second_map.Count));\r
+ //\r
+ looney := second_map[TNumberz.SIX];\r
+ Expect( Assigned(looney), 'Assigned(looney) = '+BoolToString(Assigned(looney)));\r
+ Expect( not looney.__isset_UserMap, 'looney.__isset_UserMap = '+BoolToString(looney.__isset_UserMap));\r
+ Expect( not looney.__isset_Xtructs, 'looney.__isset_Xtructs = '+BoolToString(looney.__isset_Xtructs));\r
+ //\r
+ for ret in [TNumberz.SIX, TNumberz.THREE] do begin\r
+ crazy := first_map[ret];\r
+ Console.WriteLine('first_map['+intToStr(Ord(ret))+']');\r
+\r
+ Expect( crazy.__isset_UserMap, 'crazy.__isset_UserMap = '+BoolToString(crazy.__isset_UserMap));\r
+ Expect( crazy.__isset_Xtructs, 'crazy.__isset_Xtructs = '+BoolToString(crazy.__isset_Xtructs));\r
+\r
+ Expect( crazy.UserMap.Count = 2, 'crazy.UserMap.Count = '+IntToStr(crazy.UserMap.Count));\r
+ Expect( crazy.UserMap[TNumberz.FIVE] = 5, 'crazy.UserMap[TNumberz.FIVE] = '+IntToStr(crazy.UserMap[TNumberz.FIVE]));\r
+ Expect( crazy.UserMap[TNumberz.EIGHT] = 8, 'crazy.UserMap[TNumberz.EIGHT] = '+IntToStr(crazy.UserMap[TNumberz.EIGHT]));\r
+\r
+ Expect( crazy.Xtructs.Count = 2, 'crazy.Xtructs.Count = '+IntToStr(crazy.Xtructs.Count));\r
+ goodbye := crazy.Xtructs[0]; // lists are ordered, so we are allowed to assume this order\r
+ hello := crazy.Xtructs[1];\r
+\r
+ Expect( goodbye.String_thing = 'Goodbye4', 'goodbye.String_thing = "'+goodbye.String_thing+'"');\r
+ Expect( goodbye.Byte_thing = 4, 'goodbye.Byte_thing = '+IntToStr(goodbye.Byte_thing));\r
+ Expect( goodbye.I32_thing = 4, 'goodbye.I32_thing = '+IntToStr(goodbye.I32_thing));\r
+ Expect( goodbye.I64_thing = 4, 'goodbye.I64_thing = '+IntToStr(goodbye.I64_thing));\r
+ Expect( goodbye.__isset_String_thing, 'goodbye.__isset_String_thing = '+BoolToString(goodbye.__isset_String_thing));\r
+ Expect( goodbye.__isset_Byte_thing, 'goodbye.__isset_Byte_thing = '+BoolToString(goodbye.__isset_Byte_thing));\r
+ Expect( goodbye.__isset_I32_thing, 'goodbye.__isset_I32_thing = '+BoolToString(goodbye.__isset_I32_thing));\r
+ Expect( goodbye.__isset_I64_thing, 'goodbye.__isset_I64_thing = '+BoolToString(goodbye.__isset_I64_thing));\r
+\r
+ Expect( hello.String_thing = 'hello', 'hello.String_thing = "'+hello.String_thing+'"');\r
+ Expect( hello.Byte_thing = 2, 'hello.Byte_thing = '+IntToStr(hello.Byte_thing));\r
+ Expect( hello.I32_thing = 2, 'hello.I32_thing = '+IntToStr(hello.I32_thing));\r
+ Expect( hello.I64_thing = 2, 'hello.I64_thing = '+IntToStr(hello.I64_thing));\r
+ Expect( hello.__isset_String_thing, 'hello.__isset_String_thing = '+BoolToString(hello.__isset_String_thing));\r
+ Expect( hello.__isset_Byte_thing, 'hello.__isset_Byte_thing = '+BoolToString(hello.__isset_Byte_thing));\r
+ Expect( hello.__isset_I32_thing, 'hello.__isset_I32_thing = '+BoolToString(hello.__isset_I32_thing));\r
+ Expect( hello.__isset_I64_thing, 'hello.__isset_I64_thing = '+BoolToString(hello.__isset_I64_thing));\r
+ end;\r
+\r
+\r
+ // multi args\r
+ StartTestGroup( 'testMulti');\r
arg0 := 1;\r
arg1 := 2;\r
arg2 := High(Int64);\r
-\r
- multiDict := TThriftDictionaryImpl<SmallInt, string>.Create;\r
- multiDict.AddOrSetValue( 1, 'one');\r
-\r
+ arg3 := TThriftDictionaryImpl<SmallInt, string>.Create;\r
+ arg3.AddOrSetValue( 1, 'one');\r
arg4 := TNumberz.FIVE;\r
arg5 := 5000000;\r
Console.WriteLine('Test Multi(' + IntToStr( arg0) + ',' +\r
IntToStr( arg1) + ',' + IntToStr( arg2) + ',' +\r
- multiDict.ToString + ',' + IntToStr( Integer( arg4)) + ',' +\r
+ arg3.ToString + ',' + IntToStr( Integer( arg4)) + ',' +\r
IntToStr( arg5) + ')');\r
\r
- Console.WriteLine('Test Oneway(1)');\r
+ i := client.testMulti( arg0, arg1, arg2, arg3, arg4, arg5);\r
+ Expect( i.String_thing = 'Hello2', 'testMulti: i.String_thing = "'+i.String_thing+'"');\r
+ Expect( i.Byte_thing = arg0, 'testMulti: i.Byte_thing = '+IntToStr(i.Byte_thing));\r
+ Expect( i.I32_thing = arg1, 'testMulti: i.I32_thing = '+IntToStr(i.I32_thing));\r
+ Expect( i.I64_thing = arg2, 'testMulti: i.I64_thing = '+IntToStr(i.I64_thing));\r
+ Expect( i.__isset_String_thing, 'testMulti: i.__isset_String_thing = '+BoolToString(i.__isset_String_thing));\r
+ Expect( i.__isset_Byte_thing, 'testMulti: i.__isset_Byte_thing = '+BoolToString(i.__isset_Byte_thing));\r
+ Expect( i.__isset_I32_thing, 'testMulti: i.__isset_I32_thing = '+BoolToString(i.__isset_I32_thing));\r
+ Expect( i.__isset_I64_thing, 'testMulti: i.__isset_I64_thing = '+BoolToString(i.__isset_I64_thing));\r
+\r
+ // multi exception\r
+ StartTestGroup( 'testMultiException(1)');\r
+ try\r
+ i := client.testMultiException( 'need more pizza', 'run out of beer');\r
+ Expect( i.String_thing = 'run out of beer', 'i.String_thing = "' +i.String_thing+ '"');\r
+ Expect( i.__isset_String_thing, 'i.__isset_String_thing = '+BoolToString(i.__isset_String_thing));\r
+ Expect( not i.__isset_Byte_thing, 'i.__isset_Byte_thing = '+BoolToString(i.__isset_Byte_thing));\r
+ Expect( not i.__isset_I32_thing, 'i.__isset_I32_thing = '+BoolToString(i.__isset_I32_thing));\r
+ Expect( not i.__isset_I64_thing, 'i.__isset_I64_thing = '+BoolToString(i.__isset_I64_thing));\r
+ except\r
+ on e:Exception do Expect( FALSE, 'Unexpected exception "'+e.ClassName+'"');\r
+ end;\r
+\r
+ StartTestGroup( 'testMultiException(Xception)');\r
+ try\r
+ i := client.testMultiException( 'Xception', 'second test');\r
+ Expect( FALSE, 'testMultiException(''Xception''): must trow an exception');\r
+ except\r
+ on x:TXception do begin\r
+ Expect( x.__isset_ErrorCode, 'x.__isset_ErrorCode = '+BoolToString(x.__isset_ErrorCode));\r
+ Expect( x.__isset_Message_, 'x.__isset_Message_ = '+BoolToString(x.__isset_Message_));\r
+ Expect( x.ErrorCode = 1001, 'x.ErrorCode = '+IntToStr(x.ErrorCode));\r
+ Expect( x.Message_ = 'This is an Xception', 'x.Message = "'+x.Message_+'"');\r
+ end;\r
+ on e:Exception do Expect( FALSE, 'Unexpected exception "'+e.ClassName+'"');\r
+ end;\r
+\r
+ StartTestGroup( 'testMultiException(Xception2)');\r
+ try\r
+ i := client.testMultiException( 'Xception2', 'third test');\r
+ Expect( FALSE, 'testMultiException(''Xception2''): must trow an exception');\r
+ except\r
+ on x:TXception2 do begin\r
+ Expect( x.__isset_ErrorCode, 'x.__isset_ErrorCode = '+BoolToString(x.__isset_ErrorCode));\r
+ Expect( x.__isset_Struct_thing, 'x.__isset_Struct_thing = '+BoolToString(x.__isset_Struct_thing));\r
+ Expect( x.ErrorCode = 2002, 'x.ErrorCode = '+IntToStr(x.ErrorCode));\r
+ Expect( x.Struct_thing.String_thing = 'This is an Xception2', 'x.Struct_thing.String_thing = "'+x.Struct_thing.String_thing+'"');\r
+ Expect( x.Struct_thing.__isset_String_thing, 'x.Struct_thing.__isset_String_thing = '+BoolToString(x.Struct_thing.__isset_String_thing));\r
+ Expect( not x.Struct_thing.__isset_Byte_thing, 'x.Struct_thing.__isset_Byte_thing = '+BoolToString(x.Struct_thing.__isset_Byte_thing));\r
+ Expect( not x.Struct_thing.__isset_I32_thing, 'x.Struct_thing.__isset_I32_thing = '+BoolToString(x.Struct_thing.__isset_I32_thing));\r
+ Expect( not x.Struct_thing.__isset_I64_thing, 'x.Struct_thing.__isset_I64_thing = '+BoolToString(x.Struct_thing.__isset_I64_thing));\r
+ end;\r
+ on e:Exception do Expect( FALSE, 'Unexpected exception "'+e.ClassName+'"');\r
+ end;\r
+\r
+\r
+ // oneway functions\r
+ StartTestGroup( 'Test Oneway(1)');\r
client.testOneway(1);\r
+ Expect( TRUE, 'Test Oneway(1)'); // success := no exception\r
\r
- Console.Write('Test Calltime()');\r
+ // call time\r
+ StartTestGroup( 'Test Calltime()');\r
StartTick := GetTIckCount;\r
-\r
for k := 0 to 1000 - 1 do\r
begin\r
client.testVoid();\r
end;\r
Console.WriteLine(' = ' + FloatToStr( (GetTickCount - StartTick) / 1000 ) + ' ms a testVoid() call' );\r
\r
+ // no more tests here\r
+ StartTestGroup( '');\r
end;\r
\r
\r
begin\r
stm := TStringStream.Create;\r
try\r
+ StartTestGroup( 'JsonProtocolTest'); // no more tests here\r
+\r
// prepare binary data\r
SetLength( binary, $100);\r
for i := Low(binary) to High(binary) do binary[i] := i;\r
finally\r
stm.Free;\r
prot := nil; //-> Release\r
+ StartTestGroup( ''); // no more tests here\r
+ end;\r
+end;\r
+\r
+\r
+procedure TClientThread.StartTestGroup( const aGroup : string);\r
+begin\r
+ FTestGroup := aGroup;\r
+ if FTestGroup <> '' then begin\r
+ Console.WriteLine('');\r
+ Console.WriteLine( aGroup+' tests');\r
+ Console.WriteLine( StringOfChar('-',60));\r
end;\r
end;\r
\r
begin\r
if aTestResult then begin\r
Inc(FSuccesses);\r
- Console.WriteLine( aTestInfo+' = OK');\r
+ Console.WriteLine( aTestInfo+': passed');\r
end\r
else begin\r
- Inc(FErrors);\r
- Console.WriteLine( aTestInfo+' = FAILED');\r
- ASSERT( FALSE); // we have a failed test!\r
+ FErrors.Add( FTestGroup+': '+aTestInfo);\r
+ Console.WriteLine( aTestInfo+': *** FAILED ***');\r
+\r
+ // We have a failed test!\r
+ // -> issue DebugBreak ONLY if a debugger is attached,\r
+ // -> unhandled DebugBreaks would cause Windows to terminate the app otherwise\r
+ if IsDebuggerPresent then asm int 3 end;\r
end;\r
end;\r
\r
\r
+procedure TClientThread.ReportResults;\r
+var nTotal : Integer;\r
+ sLine : string;\r
+begin\r
+ // prevent us from stupid DIV/0 errors\r
+ nTotal := FSuccesses + FErrors.Count;\r
+ if nTotal = 0 then begin\r
+ Console.WriteLine('No results logged');\r
+ Exit;\r
+ end;\r
+\r
+ Console.WriteLine('');\r
+ Console.WriteLine( StringOfChar('=',60));\r
+ Console.WriteLine( IntToStr(nTotal)+' tests performed');\r
+ Console.WriteLine( IntToStr(FSuccesses)+' tests succeeded ('+IntToStr(round(100*FSuccesses/nTotal))+'%)');\r
+ Console.WriteLine( IntToStr(FErrors.Count)+' tests failed ('+IntToStr(round(100*FErrors.Count/nTotal))+'%)');\r
+ Console.WriteLine( StringOfChar('=',60));\r
+ if FErrors.Count > 0 then begin\r
+ Console.WriteLine('FAILED TESTS:');\r
+ for sLine in FErrors do Console.WriteLine('- '+sLine);\r
+ Console.WriteLine( StringOfChar('=',60));\r
+ end;\r
+ Console.WriteLine('');\r
+end;\r
+\r
+\r
constructor TClientThread.Create(ATransport: ITransport; AProtocol : IProtocol; ANumIteration: Integer);\r
begin\r
inherited Create( True );\r
FTransport := ATransport;\r
FProtocol := AProtocol;\r
FConsole := TThreadConsole.Create( Self );\r
+\r
+ // error list: keep correct order, allow for duplicates\r
+ FErrors := TStringList.Create;\r
+ FErrors.Sorted := FALSE;\r
+ FErrors.Duplicates := dupAccept;\r
end;\r
\r
destructor TClientThread.Destroy;\r
begin\r
- FConsole.Free;\r
+ FreeAndNil( FConsole);\r
+ FreeAndNil( FErrors);\r
inherited;\r
end;\r
\r
i : Integer;\r
proc : TThreadProcedure;\r
begin\r
- for i := 0 to FNumIteration - 1 do\r
- begin\r
- ClientTest;\r
- JSONProtocolReadWriteTest;\r
+ // perform all tests\r
+ try\r
+ for i := 0 to FNumIteration - 1 do\r
+ begin\r
+ ClientTest;\r
+ JSONProtocolReadWriteTest;\r
+ end;\r
+ except\r
+ on e:Exception do Expect( FALSE, 'unexpected exception: "'+e.message+'"');\r
end;\r
\r
+ // report the outcome\r
+ ReportResults;\r
+\r
+ // shutdown\r
proc := procedure\r
begin\r
if FTransport <> nil then\r