From df4cffd34a54988a3faa50c3ddb33d263fa08693 Mon Sep 17 00:00:00 2001 From: Bryan Duxbury Date: Tue, 15 Mar 2011 17:16:09 +0000 Subject: [PATCH] THRIFT-1093. py: several bugs in python TCompactProtocol Patch; Will Pierce git-svn-id: https://svn.apache.org/repos/asf/thrift/trunk@1081864 13f79535-47bb-0310-9956-ffa450edef68 --- lib/py/src/protocol/TCompactProtocol.py | 18 ++-- test/ThriftTest.thrift | 13 +++ test/py/SerializationTest.py | 104 +++++++++++++++++++++++- 3 files changed, 128 insertions(+), 7 deletions(-) diff --git a/lib/py/src/protocol/TCompactProtocol.py b/lib/py/src/protocol/TCompactProtocol.py index fbc156a8..7ff07987 100644 --- a/lib/py/src/protocol/TCompactProtocol.py +++ b/lib/py/src/protocol/TCompactProtocol.py @@ -52,8 +52,9 @@ def readVarint(trans): shift += 7 class CompactType: - TRUE = 1 - FALSE = 2 + STOP = 0x00 + TRUE = 0x01 + FALSE = 0x02 BYTE = 0x03 I16 = 0x04 I32 = 0x05 @@ -65,7 +66,8 @@ class CompactType: MAP = 0x0B STRUCT = 0x0C -CTYPES = {TType.BOOL: CompactType.TRUE, # used for collection +CTYPES = {TType.STOP: CompactType.STOP, + TType.BOOL: CompactType.TRUE, # used for collection TType.BYTE: CompactType.BYTE, TType.I16: CompactType.I16, TType.I32: CompactType.I32, @@ -75,7 +77,7 @@ CTYPES = {TType.BOOL: CompactType.TRUE, # used for collection TType.STRUCT: CompactType.STRUCT, TType.LIST: CompactType.LIST, TType.SET: CompactType.SET, - TType.MAP: CompactType.MAP, + TType.MAP: CompactType.MAP } TTYPES = {} @@ -196,11 +198,15 @@ class TCompactProtocol(TProtocolBase): def writeBool(self, bool): if self.state == BOOL_WRITE: - self.__writeFieldHeader(types[bool], self.__bool_fid) + if bool: + ctype = CompactType.TRUE + else: + ctype = CompactType.FALSE + self.__writeFieldHeader(ctype, self.__bool_fid) elif self.state == CONTAINER_WRITE: self.__writeByte(int(bool)) else: - raise AssertetionError, "Invalid state in compact protocol" + raise AssertionError, "Invalid state in compact protocol" writeByte = writer(__writeByte) writeI16 = writer(__writeI16) diff --git a/test/ThriftTest.thrift b/test/ThriftTest.thrift index 63a533a6..da2aaf7e 100644 --- a/test/ThriftTest.thrift +++ b/test/ThriftTest.thrift @@ -194,3 +194,16 @@ struct ListTypeVersioningV2 { struct GuessProtocolStruct { 7: map map_field, } + +struct LargeDeltas { + 1: Bools b1, + 10: Bools b10, + 100: Bools b100, + 500: bool check_true, + 1000: Bools b1000, + 1500: bool check_false, + 2000: VersioningTestV2 vertwo2000, + 2500: set a_set2500, + 3000: VersioningTestV2 vertwo3000, + 4000: list big_numbers +} diff --git a/test/py/SerializationTest.py b/test/py/SerializationTest.py index 9e18aea4..3ba76fba 100755 --- a/test/py/SerializationTest.py +++ b/test/py/SerializationTest.py @@ -24,6 +24,7 @@ sys.path.insert(0, './gen-py') sys.path.insert(0, glob.glob('../../lib/py/build/lib.*')[0]) from ThriftTest.ttypes import * +from DebugProtoTest.ttypes import CompactProtoTestStruct, Empty from thrift.transport import TTransport from thrift.transport import TSocket from thrift.protocol import TBinaryProtocol, TCompactProtocol @@ -49,12 +50,76 @@ class AbstractTest(unittest.TestCase): newdouble=5.0, newstruct=Bonk(message="Hello!", type=123), newlist=[7,8,9], - newset=[42,1,8], + newset=set([42,1,8]), newmap={1:2,2:3}, newstring="Hola!", end_in_both=54321, ) + self.bools = Bools(im_true=True, im_false=False) + self.bools_flipped = Bools(im_true=False, im_false=True) + + self.large_deltas = LargeDeltas ( + b1=self.bools, + b10=self.bools_flipped, + b100=self.bools, + check_true=True, + b1000=self.bools_flipped, + check_false=False, + vertwo2000=VersioningTestV2(newstruct=Bonk(message='World!', type=314)), + a_set2500=set(['lazy', 'brown', 'cow']), + vertwo3000=VersioningTestV2(newset=set([2, 3, 5, 7, 11])), + big_numbers=[2**8, 2**16, 2**31-1, -(2**31-1)] + ) + + self.compact_struct = CompactProtoTestStruct( + a_byte = 127, + a_i16=32000, + a_i32=1000000000, + a_i64=0xffffffffff, + a_double=5.6789, + a_string="my string", + true_field=True, + false_field=False, + empty_struct_field=Empty(), + byte_list=[-127, -1, 0, 1, 127], + i16_list=[-1, 0, 1, 0x7fff], + i32_list= [-1, 0, 0xff, 0xffff, 0xffffff, 0x7fffffff], + i64_list=[-1, 0, 0xff, 0xffff, 0xffffff, 0xffffffff, 0xffffffffff, 0xffffffffffff, 0xffffffffffffff, 0x7fffffffffffffff], + double_list=[0.1, 0.2, 0.3], + string_list=["first", "second", "third"], + boolean_list=[True, True, True, False, False, False], + struct_list=[Empty(), Empty()], + byte_set=set([-127, -1, 0, 1, 127]), + i16_set=set([-1, 0, 1, 0x7fff]), + i32_set=set([1, 2, 3]), + i64_set=set([-1, 0, 0xff, 0xffff, 0xffffff, 0xffffffff, 0xffffffffff, 0xffffffffffff, 0xffffffffffffff, 0x7fffffffffffffff]), + double_set=set([0.1, 0.2, 0.3]), + string_set=set(["first", "second", "third"]), + boolean_set=set([True, False]), + #struct_set=set([Empty()]), # unhashable instance + byte_byte_map={1 : 2}, + i16_byte_map={1 : 1, -1 : 1, 0x7fff : 1}, + i32_byte_map={1 : 1, -1 : 1, 0x7fffffff : 1}, + i64_byte_map={0 : 1, 1 : 1, -1 : 1, 0x7fffffffffffffff : 1}, + double_byte_map={-1.1 : 1, 1.1 : 1}, + string_byte_map={"first" : 1, "second" : 2, "third" : 3, "" : 0}, + boolean_byte_map={True : 1, False: 0}, + byte_i16_map={1 : 1, 2 : -1, 3 : 0x7fff}, + byte_i32_map={1 : 1, 2 : -1, 3 : 0x7fffffff}, + byte_i64_map={1 : 1, 2 : -1, 3 : 0x7fffffffffffffff}, + byte_double_map={1 : 0.1, 2 : -0.1, 3 : 1000000.1}, + byte_string_map={1 : "", 2 : "blah", 3 : "loooooooooooooong string"}, + byte_boolean_map={1 : True, 2 : False}, + #list_byte_map # unhashable + #set_byte_map={set([1, 2, 3]) : 1, set([0, 1]) : 2, set([]) : 0}, # unhashable + #map_byte_map # unhashable + byte_map_map={0 : {}, 1 : {1 : 1}, 2 : {1 : 1, 2 : 2}}, + byte_set_map={0 : set([]), 1 : set([1]), 2 : set([1, 2])}, + byte_list_map={0 : [], 1 : [1], 2 : [1, 2]}, + ) + + def _serialize(self, obj): trans = TTransport.TMemoryBuffer() prot = self.protocol_factory.getProtocol(trans) @@ -77,6 +142,30 @@ class AbstractTest(unittest.TestCase): self.assertEquals(obj.begin_in_both, self.v2obj.begin_in_both) self.assertEquals(obj.end_in_both, self.v2obj.end_in_both) + def testSerializeV1(self): + obj = self._deserialize(VersioningTestV1, self._serialize(self.v1obj)) + self.assertEquals(obj, self.v1obj) + + def testSerializeV2(self): + obj = self._deserialize(VersioningTestV2, self._serialize(self.v2obj)) + self.assertEquals(obj, self.v2obj) + + def testBools(self): + self.assertNotEquals(self.bools, self.bools_flipped) + obj = self._deserialize(Bools, self._serialize(self.bools)) + self.assertEquals(obj, self.bools) + obj = self._deserialize(Bools, self._serialize(self.bools_flipped)) + self.assertEquals(obj, self.bools_flipped) + + def testLargeDeltas(self): + # test large field deltas (meaningful in CompactProto only) + obj = self._deserialize(LargeDeltas, self._serialize(self.large_deltas)) + self.assertEquals(obj, self.large_deltas) + + def testCompactStruct(self): + # test large field deltas (meaningful in CompactProto only) + obj = self._deserialize(CompactProtoTestStruct, self._serialize(self.compact_struct)) + self.assertEquals(obj, self.compact_struct) class NormalBinaryTest(AbstractTest): protocol_factory = TBinaryProtocol.TBinaryProtocolFactory() @@ -139,6 +228,19 @@ class SerializersTest(unittest.TestCase): deserialize(objcopy, serialize(obj)) self.assertEquals(obj, objcopy) + # test booleans + obj = Bools(im_true=True, im_false=False) + objcopy = Bools() + deserialize(objcopy, serialize(obj)) + self.assertEquals(obj, objcopy) + + # test enums + for num, name in Numberz._VALUES_TO_NAMES.iteritems(): + obj = Bonk(message='enum Numberz value %d is string %s' % (num, name), type=num) + objcopy = Bonk() + deserialize(objcopy, serialize(obj)) + self.assertEquals(obj, objcopy) + def suite(): suite = unittest.TestSuite() -- 2.17.1