blob: e77b115c676fce84b877eb5f303911adfa2f8b1d [file] [log] [blame]
David Reiss382fc302007-08-25 18:01:30 +00001#!/usr/bin/env python
David Reissea2cba82009-03-30 21:35:00 +00002
3#
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 Reiss382fc302007-08-25 18:01:30 +000022r"""
David Reiss0c87ad42008-12-02 02:11:13 +000023thrift --gen py DebugProtoTest.thrift
David Reiss382fc302007-08-25 18:01:30 +000024./FastbinaryTest.py
25"""
26
27# TODO(dreiss): Test error cases. Check for memory leaks.
28
29import sys
30sys.path.append('./gen-py')
31
32import math
33from DebugProtoTest import Srv
34from DebugProtoTest.ttypes import *
35from thrift.transport import TTransport
36from thrift.protocol import TBinaryProtocol
37
38import timeit
39from cStringIO import StringIO
40from copy import deepcopy
41from pprint import pprint
42
43class TDevNullTransport(TTransport.TTransportBase):
44 def __init__(self):
45 pass
46 def isOpen(self):
47 return True
48
49ooe1 = OneOfEach()
50ooe1.im_true = True;
51ooe1.im_false = False;
52ooe1.a_bite = 0xd6;
53ooe1.integer16 = 27000;
54ooe1.integer32 = 1<<24;
55ooe1.integer64 = 6000 * 1000 * 1000;
56ooe1.double_precision = math.pi;
57ooe1.some_characters = "Debug THIS!";
58ooe1.zomg_unicode = "\xd7\n\a\t";
59
60ooe2 = OneOfEach();
61ooe2.integer16 = 16;
62ooe2.integer32 = 32;
63ooe2.integer64 = 64;
64ooe2.double_precision = (math.sqrt(5)+1)/2;
65ooe2.some_characters = ":R (me going \"rrrr\")";
66ooe2.zomg_unicode = "\xd3\x80\xe2\x85\xae\xce\x9d\x20"\
67 "\xd0\x9d\xce\xbf\xe2\x85\xbf\xd0\xbe"\
68 "\xc9\xa1\xd0\xb3\xd0\xb0\xcf\x81\xe2\x84\x8e"\
69 "\x20\xce\x91\x74\x74\xce\xb1\xe2\x85\xbd\xce\xba"\
70 "\xc7\x83\xe2\x80\xbc";
71
72hm = HolyMoley({"big":[], "contain":set(), "bonks":{}})
73hm.big.append(ooe1)
74hm.big.append(ooe2)
75hm.big[0].a_bite = 0x22;
76hm.big[1].a_bite = 0x22;
77
78hm.contain.add(("and a one", "and a two"))
79hm.contain.add(("then a one, two", "three!", "FOUR!"))
80hm.contain.add(())
81
82hm.bonks["nothing"] = [];
83hm.bonks["something"] = [
84 Bonk({"type":1, "message":"Wait."}),
85 Bonk({"type":2, "message":"What?"}),
86]
87hm.bonks["poe"] = [
88 Bonk({"type":3, "message":"quoth"}),
89 Bonk({"type":4, "message":"the raven"}),
90 Bonk({"type":5, "message":"nevermore"}),
91]
92
93rs = RandomStuff()
94rs.a = 1
95rs.b = 2
96rs.c = 3
97rs.myintlist = range(20)
98rs.maps = {1:Wrapper({"foo":Empty()}),2:Wrapper({"foo":Empty()})}
99rs.bigint = 124523452435L
100rs.triple = 3.14
101
David Reiss2c2e6d22007-09-05 01:14:09 +0000102# make sure this splits two buffers in a buffered protocol
103rshuge = RandomStuff()
104rshuge.myintlist=range(10000)
105
David Reiss382fc302007-08-25 18:01:30 +0000106my_zero = Srv.Janky_result({"arg":5})
107my_nega = Srv.Janky_args({"success":6})
108
109def checkWrite(o):
110 trans_fast = TTransport.TMemoryBuffer()
111 trans_slow = TTransport.TMemoryBuffer()
112 prot_fast = TBinaryProtocol.TBinaryProtocolAccelerated(trans_fast)
113 prot_slow = TBinaryProtocol.TBinaryProtocol(trans_slow)
114
115 o.write(prot_fast)
116 o.write(prot_slow)
117 ORIG = trans_slow.getvalue()
118 MINE = trans_fast.getvalue()
119 if ORIG != MINE:
120 print "mine: %s\norig: %s" % (repr(MINE), repr(ORIG))
121
122def checkRead(o):
123 prot = TBinaryProtocol.TBinaryProtocol(TTransport.TMemoryBuffer())
124 o.write(prot)
David Reiss2c2e6d22007-09-05 01:14:09 +0000125
126 slow_version_binary = prot.trans.getvalue()
David Reiss0c90f6f2008-02-06 22:18:40 +0000127
David Reiss382fc302007-08-25 18:01:30 +0000128 prot = TBinaryProtocol.TBinaryProtocolAccelerated(
David Reiss2c2e6d22007-09-05 01:14:09 +0000129 TTransport.TMemoryBuffer(slow_version_binary))
130 c = o.__class__()
131 c.read(prot)
132 if c != o:
133 print "copy: "
134 pprint(eval(repr(c)))
135 print "orig: "
136 pprint(eval(repr(o)))
137
138 prot = TBinaryProtocol.TBinaryProtocolAccelerated(
139 TTransport.TBufferedTransport(
140 TTransport.TMemoryBuffer(slow_version_binary)))
David Reiss382fc302007-08-25 18:01:30 +0000141 c = o.__class__()
142 c.read(prot)
143 if c != o:
144 print "copy: "
145 pprint(eval(repr(c)))
146 print "orig: "
147 pprint(eval(repr(o)))
148
149
150def doTest():
151 checkWrite(hm)
152 no_set = deepcopy(hm)
153 no_set.contain = set()
154 checkRead(no_set)
155 checkWrite(rs)
156 checkRead(rs)
David Reiss2c2e6d22007-09-05 01:14:09 +0000157 checkWrite(rshuge)
158 checkRead(rshuge)
David Reiss382fc302007-08-25 18:01:30 +0000159 checkWrite(my_zero)
160 checkRead(my_zero)
161 checkRead(Backwards({"first_tag2":4, "second_tag1":2}))
162 try:
163 checkWrite(my_nega)
164 print "Hey, did this get fixed?"
165 except AttributeError:
166 # Sorry, doesn't work with negative tags.
167 pass
168
169 # One case where the serialized form changes, but only superficially.
170 o = Backwards({"first_tag2":4, "second_tag1":2})
171 trans_fast = TTransport.TMemoryBuffer()
172 trans_slow = TTransport.TMemoryBuffer()
173 prot_fast = TBinaryProtocol.TBinaryProtocolAccelerated(trans_fast)
174 prot_slow = TBinaryProtocol.TBinaryProtocol(trans_slow)
175
176 o.write(prot_fast)
177 o.write(prot_slow)
178 ORIG = trans_slow.getvalue()
179 MINE = trans_fast.getvalue()
180 if ORIG == MINE:
181 print "That shouldn't happen."
182
183
184 prot = TBinaryProtocol.TBinaryProtocolAccelerated(TTransport.TMemoryBuffer())
185 o.write(prot)
186 prot = TBinaryProtocol.TBinaryProtocol(
187 TTransport.TMemoryBuffer(
188 prot.trans.getvalue()))
189 c = o.__class__()
190 c.read(prot)
191 if c != o:
192 print "copy: "
193 pprint(eval(repr(c)))
194 print "orig: "
195 pprint(eval(repr(o)))
196
197
198
199def doBenchmark():
200
201 iters = 25000
202
203 setup = """
204from __main__ import hm, rs, TDevNullTransport
205from thrift.protocol import TBinaryProtocol
206trans = TDevNullTransport()
207prot = TBinaryProtocol.TBinaryProtocol%s(trans)
208"""
209
210 setup_fast = setup % "Accelerated"
211 setup_slow = setup % ""
212
213 print "Starting Benchmarks"
214
215 print "HolyMoley Standard = %f" % \
216 timeit.Timer('hm.write(prot)', setup_slow).timeit(number=iters)
217 print "HolyMoley Acceler. = %f" % \
218 timeit.Timer('hm.write(prot)', setup_fast).timeit(number=iters)
219
220 print "FastStruct Standard = %f" % \
221 timeit.Timer('rs.write(prot)', setup_slow).timeit(number=iters)
222 print "FastStruct Acceler. = %f" % \
223 timeit.Timer('rs.write(prot)', setup_fast).timeit(number=iters)
224
225
226
227doTest()
228doBenchmark()
229