blob: 3ba76fba266ac06f89904d618add32b093626ed7 [file] [log] [blame]
David Reiss9ff3b9d2008-02-15 01:10:23 +00001#!/usr/bin/env python
2
David Reissea2cba82009-03-30 21:35:00 +00003#
4# Licensed to the Apache Software Foundation (ASF) under one
5# or more contributor license agreements. See the NOTICE file
6# distributed with this work for additional information
7# regarding copyright ownership. The ASF licenses this file
8# to you under the Apache License, Version 2.0 (the
9# "License"); you may not use this file except in compliance
10# with the License. You may obtain a copy of the License at
11#
12# http://www.apache.org/licenses/LICENSE-2.0
13#
14# Unless required by applicable law or agreed to in writing,
15# software distributed under the License is distributed on an
16# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17# KIND, either express or implied. See the License for the
18# specific language governing permissions and limitations
19# under the License.
20#
21
David Reiss9ff3b9d2008-02-15 01:10:23 +000022import sys, glob
23sys.path.insert(0, './gen-py')
24sys.path.insert(0, glob.glob('../../lib/py/build/lib.*')[0])
25
26from ThriftTest.ttypes import *
Bryan Duxburydf4cffd2011-03-15 17:16:09 +000027from DebugProtoTest.ttypes import CompactProtoTestStruct, Empty
David Reiss9ff3b9d2008-02-15 01:10:23 +000028from thrift.transport import TTransport
29from thrift.transport import TSocket
David Reissabafd792010-09-27 17:28:15 +000030from thrift.protocol import TBinaryProtocol, TCompactProtocol
David Reiss6acc2692010-02-26 00:56:02 +000031from thrift.TSerialization import serialize, deserialize
David Reiss9ff3b9d2008-02-15 01:10:23 +000032import unittest
33import time
34
35class AbstractTest(unittest.TestCase):
36
37 def setUp(self):
David Reiss46bb4ae2009-01-14 22:34:15 +000038 self.v1obj = VersioningTestV1(
David Reiss9ff3b9d2008-02-15 01:10:23 +000039 begin_in_both=12345,
David Reissa528f542009-03-24 22:48:40 +000040 old_string='aaa',
David Reiss9ff3b9d2008-02-15 01:10:23 +000041 end_in_both=54321,
David Reiss46bb4ae2009-01-14 22:34:15 +000042 )
David Reiss9ff3b9d2008-02-15 01:10:23 +000043
David Reiss46bb4ae2009-01-14 22:34:15 +000044 self.v2obj = VersioningTestV2(
David Reiss9ff3b9d2008-02-15 01:10:23 +000045 begin_in_both=12345,
46 newint=1,
47 newbyte=2,
48 newshort=3,
49 newlong=4,
50 newdouble=5.0,
David Reiss46bb4ae2009-01-14 22:34:15 +000051 newstruct=Bonk(message="Hello!", type=123),
David Reiss9ff3b9d2008-02-15 01:10:23 +000052 newlist=[7,8,9],
Bryan Duxburydf4cffd2011-03-15 17:16:09 +000053 newset=set([42,1,8]),
David Reiss9ff3b9d2008-02-15 01:10:23 +000054 newmap={1:2,2:3},
55 newstring="Hola!",
56 end_in_both=54321,
David Reiss46bb4ae2009-01-14 22:34:15 +000057 )
David Reiss9ff3b9d2008-02-15 01:10:23 +000058
Bryan Duxburydf4cffd2011-03-15 17:16:09 +000059 self.bools = Bools(im_true=True, im_false=False)
60 self.bools_flipped = Bools(im_true=False, im_false=True)
61
62 self.large_deltas = LargeDeltas (
63 b1=self.bools,
64 b10=self.bools_flipped,
65 b100=self.bools,
66 check_true=True,
67 b1000=self.bools_flipped,
68 check_false=False,
69 vertwo2000=VersioningTestV2(newstruct=Bonk(message='World!', type=314)),
70 a_set2500=set(['lazy', 'brown', 'cow']),
71 vertwo3000=VersioningTestV2(newset=set([2, 3, 5, 7, 11])),
72 big_numbers=[2**8, 2**16, 2**31-1, -(2**31-1)]
73 )
74
75 self.compact_struct = CompactProtoTestStruct(
76 a_byte = 127,
77 a_i16=32000,
78 a_i32=1000000000,
79 a_i64=0xffffffffff,
80 a_double=5.6789,
81 a_string="my string",
82 true_field=True,
83 false_field=False,
84 empty_struct_field=Empty(),
85 byte_list=[-127, -1, 0, 1, 127],
86 i16_list=[-1, 0, 1, 0x7fff],
87 i32_list= [-1, 0, 0xff, 0xffff, 0xffffff, 0x7fffffff],
88 i64_list=[-1, 0, 0xff, 0xffff, 0xffffff, 0xffffffff, 0xffffffffff, 0xffffffffffff, 0xffffffffffffff, 0x7fffffffffffffff],
89 double_list=[0.1, 0.2, 0.3],
90 string_list=["first", "second", "third"],
91 boolean_list=[True, True, True, False, False, False],
92 struct_list=[Empty(), Empty()],
93 byte_set=set([-127, -1, 0, 1, 127]),
94 i16_set=set([-1, 0, 1, 0x7fff]),
95 i32_set=set([1, 2, 3]),
96 i64_set=set([-1, 0, 0xff, 0xffff, 0xffffff, 0xffffffff, 0xffffffffff, 0xffffffffffff, 0xffffffffffffff, 0x7fffffffffffffff]),
97 double_set=set([0.1, 0.2, 0.3]),
98 string_set=set(["first", "second", "third"]),
99 boolean_set=set([True, False]),
100 #struct_set=set([Empty()]), # unhashable instance
101 byte_byte_map={1 : 2},
102 i16_byte_map={1 : 1, -1 : 1, 0x7fff : 1},
103 i32_byte_map={1 : 1, -1 : 1, 0x7fffffff : 1},
104 i64_byte_map={0 : 1, 1 : 1, -1 : 1, 0x7fffffffffffffff : 1},
105 double_byte_map={-1.1 : 1, 1.1 : 1},
106 string_byte_map={"first" : 1, "second" : 2, "third" : 3, "" : 0},
107 boolean_byte_map={True : 1, False: 0},
108 byte_i16_map={1 : 1, 2 : -1, 3 : 0x7fff},
109 byte_i32_map={1 : 1, 2 : -1, 3 : 0x7fffffff},
110 byte_i64_map={1 : 1, 2 : -1, 3 : 0x7fffffffffffffff},
111 byte_double_map={1 : 0.1, 2 : -0.1, 3 : 1000000.1},
112 byte_string_map={1 : "", 2 : "blah", 3 : "loooooooooooooong string"},
113 byte_boolean_map={1 : True, 2 : False},
114 #list_byte_map # unhashable
115 #set_byte_map={set([1, 2, 3]) : 1, set([0, 1]) : 2, set([]) : 0}, # unhashable
116 #map_byte_map # unhashable
117 byte_map_map={0 : {}, 1 : {1 : 1}, 2 : {1 : 1, 2 : 2}},
118 byte_set_map={0 : set([]), 1 : set([1]), 2 : set([1, 2])},
119 byte_list_map={0 : [], 1 : [1], 2 : [1, 2]},
120 )
121
122
David Reiss9ff3b9d2008-02-15 01:10:23 +0000123 def _serialize(self, obj):
124 trans = TTransport.TMemoryBuffer()
125 prot = self.protocol_factory.getProtocol(trans)
126 obj.write(prot)
127 return trans.getvalue()
128
129 def _deserialize(self, objtype, data):
130 prot = self.protocol_factory.getProtocol(TTransport.TMemoryBuffer(data))
131 ret = objtype()
132 ret.read(prot)
133 return ret
134
135 def testForwards(self):
136 obj = self._deserialize(VersioningTestV2, self._serialize(self.v1obj))
David Reiss1cc0c5e2008-10-17 19:30:35 +0000137 self.assertEquals(obj.begin_in_both, self.v1obj.begin_in_both)
138 self.assertEquals(obj.end_in_both, self.v1obj.end_in_both)
David Reiss9ff3b9d2008-02-15 01:10:23 +0000139
140 def testBackwards(self):
141 obj = self._deserialize(VersioningTestV1, self._serialize(self.v2obj))
David Reiss1cc0c5e2008-10-17 19:30:35 +0000142 self.assertEquals(obj.begin_in_both, self.v2obj.begin_in_both)
143 self.assertEquals(obj.end_in_both, self.v2obj.end_in_both)
David Reiss9ff3b9d2008-02-15 01:10:23 +0000144
Bryan Duxburydf4cffd2011-03-15 17:16:09 +0000145 def testSerializeV1(self):
146 obj = self._deserialize(VersioningTestV1, self._serialize(self.v1obj))
147 self.assertEquals(obj, self.v1obj)
148
149 def testSerializeV2(self):
150 obj = self._deserialize(VersioningTestV2, self._serialize(self.v2obj))
151 self.assertEquals(obj, self.v2obj)
152
153 def testBools(self):
154 self.assertNotEquals(self.bools, self.bools_flipped)
155 obj = self._deserialize(Bools, self._serialize(self.bools))
156 self.assertEquals(obj, self.bools)
157 obj = self._deserialize(Bools, self._serialize(self.bools_flipped))
158 self.assertEquals(obj, self.bools_flipped)
159
160 def testLargeDeltas(self):
161 # test large field deltas (meaningful in CompactProto only)
162 obj = self._deserialize(LargeDeltas, self._serialize(self.large_deltas))
163 self.assertEquals(obj, self.large_deltas)
164
165 def testCompactStruct(self):
166 # test large field deltas (meaningful in CompactProto only)
167 obj = self._deserialize(CompactProtoTestStruct, self._serialize(self.compact_struct))
168 self.assertEquals(obj, self.compact_struct)
David Reiss9ff3b9d2008-02-15 01:10:23 +0000169
170class NormalBinaryTest(AbstractTest):
171 protocol_factory = TBinaryProtocol.TBinaryProtocolFactory()
172
173class AcceleratedBinaryTest(AbstractTest):
174 protocol_factory = TBinaryProtocol.TBinaryProtocolAcceleratedFactory()
175
David Reissabafd792010-09-27 17:28:15 +0000176class CompactProtocolTest(AbstractTest):
177 protocol_factory = TCompactProtocol.TCompactProtocolFactory()
David Reiss9ff3b9d2008-02-15 01:10:23 +0000178
David Reiss4c591c92009-01-31 21:39:25 +0000179class AcceleratedFramedTest(unittest.TestCase):
180 def testSplit(self):
181 """Test FramedTransport and BinaryProtocolAccelerated
182
183 Tests that TBinaryProtocolAccelerated and TFramedTransport
184 play nicely together when a read spans a frame"""
185
186 protocol_factory = TBinaryProtocol.TBinaryProtocolAcceleratedFactory()
187 bigstring = "".join(chr(byte) for byte in range(ord("a"), ord("z")+1))
188
189 databuf = TTransport.TMemoryBuffer()
190 prot = protocol_factory.getProtocol(databuf)
191 prot.writeI32(42)
192 prot.writeString(bigstring)
193 prot.writeI16(24)
194 data = databuf.getvalue()
195 cutpoint = len(data)/2
196 parts = [ data[:cutpoint], data[cutpoint:] ]
197
198 framed_buffer = TTransport.TMemoryBuffer()
199 framed_writer = TTransport.TFramedTransport(framed_buffer)
200 for part in parts:
201 framed_writer.write(part)
202 framed_writer.flush()
203 self.assertEquals(len(framed_buffer.getvalue()), len(data) + 8)
204
205 # Recreate framed_buffer so we can read from it.
206 framed_buffer = TTransport.TMemoryBuffer(framed_buffer.getvalue())
207 framed_reader = TTransport.TFramedTransport(framed_buffer)
208 prot = protocol_factory.getProtocol(framed_reader)
209 self.assertEqual(prot.readI32(), 42)
210 self.assertEqual(prot.readString(), bigstring)
211 self.assertEqual(prot.readI16(), 24)
212
David Reiss6acc2692010-02-26 00:56:02 +0000213class SerializersTest(unittest.TestCase):
214
215 def testSerializeThenDeserialize(self):
216 obj = Xtruct2(i32_thing=1,
217 struct_thing=Xtruct(string_thing="foo"))
218
219 s1 = serialize(obj)
220 for i in range(10):
221 self.assertEquals(s1, serialize(obj))
222 objcopy = Xtruct2()
223 deserialize(objcopy, serialize(obj))
224 self.assertEquals(obj, objcopy)
225
226 obj = Xtruct(string_thing="bar")
227 objcopy = Xtruct()
228 deserialize(objcopy, serialize(obj))
229 self.assertEquals(obj, objcopy)
David Reiss4c591c92009-01-31 21:39:25 +0000230
Bryan Duxburydf4cffd2011-03-15 17:16:09 +0000231 # test booleans
232 obj = Bools(im_true=True, im_false=False)
233 objcopy = Bools()
234 deserialize(objcopy, serialize(obj))
235 self.assertEquals(obj, objcopy)
236
237 # test enums
238 for num, name in Numberz._VALUES_TO_NAMES.iteritems():
239 obj = Bonk(message='enum Numberz value %d is string %s' % (num, name), type=num)
240 objcopy = Bonk()
241 deserialize(objcopy, serialize(obj))
242 self.assertEquals(obj, objcopy)
243
David Reiss4c591c92009-01-31 21:39:25 +0000244
David Reiss9ff3b9d2008-02-15 01:10:23 +0000245def suite():
246 suite = unittest.TestSuite()
247 loader = unittest.TestLoader()
248
249 suite.addTest(loader.loadTestsFromTestCase(NormalBinaryTest))
250 suite.addTest(loader.loadTestsFromTestCase(AcceleratedBinaryTest))
David Reissabafd792010-09-27 17:28:15 +0000251 suite.addTest(loader.loadTestsFromTestCase(CompactProtocolTest))
David Reiss4c591c92009-01-31 21:39:25 +0000252 suite.addTest(loader.loadTestsFromTestCase(AcceleratedFramedTest))
David Reiss6acc2692010-02-26 00:56:02 +0000253 suite.addTest(loader.loadTestsFromTestCase(SerializersTest))
David Reiss9ff3b9d2008-02-15 01:10:23 +0000254 return suite
255
256if __name__ == "__main__":
257 unittest.main(defaultTest="suite", testRunner=unittest.TextTestRunner(verbosity=2))