blob: 7fe48f655840731e141423bde40068effb6cfcf7 [file] [log] [blame]
Mark Slee57cc25e2007-02-28 21:43:54 +00001#!/usr/bin/env python
Mark Sleefc89d392006-09-04 00:04:39 +00002
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
Jens Geyerd629ea02015-09-23 21:16:50 +020022import glob
23import os
24import sys
Mark Slee57cc25e2007-02-28 21:43:54 +000025import time
Jens Geyerd629ea02015-09-23 21:16:50 +020026import unittest
Mark Slee5299a952007-10-05 00:13:24 +000027from optparse import OptionParser
Mark Slee57cc25e2007-02-28 21:43:54 +000028
Mark Slee5299a952007-10-05 00:13:24 +000029parser = OptionParser()
Roger Meierf4eec7a2011-09-11 18:16:21 +000030parser.add_option('--genpydir', type='string', dest='genpydir',
31 default='gen-py',
32 help='include this local directory in sys.path for locating generated code')
David Reiss74421272008-11-07 23:09:31 +000033parser.add_option("--port", type="int", dest="port",
34 help="connect to server at port")
35parser.add_option("--host", type="string", dest="host",
36 help="connect to server")
Bryan Duxbury16066592011-03-22 18:06:04 +000037parser.add_option("--zlib", action="store_true", dest="zlib",
38 help="use zlib wrapper for compressed transport")
39parser.add_option("--ssl", action="store_true", dest="ssl",
40 help="use SSL for encrypted transport")
David Reissf78ec2b2009-01-31 21:59:32 +000041parser.add_option("--http", dest="http_path",
42 help="Use the HTTP transport with the specified path")
Roger Meier76150722014-05-31 22:22:07 +020043parser.add_option('-v', '--verbose', action="store_const",
David Reiss74421272008-11-07 23:09:31 +000044 dest="verbose", const=2,
45 help="verbose output")
Roger Meier76150722014-05-31 22:22:07 +020046parser.add_option('-q', '--quiet', action="store_const",
David Reiss74421272008-11-07 23:09:31 +000047 dest="verbose", const=0,
48 help="minimal output")
Roger Meier76150722014-05-31 22:22:07 +020049parser.add_option('--protocol', dest="proto", type="string",
50 help="protocol to use, one of: accel, binary, compact, json")
51parser.add_option('--transport', dest="trans", type="string",
52 help="transport to use, one of: buffered, framed")
Bryan Duxbury59d4efd2011-03-21 17:38:22 +000053parser.set_defaults(framed=False, http_path=None, verbose=1, host='localhost', port=9090, proto='binary')
David Reiss74421272008-11-07 23:09:31 +000054options, args = parser.parse_args()
Mark Sleea3302652006-10-25 19:03:32 +000055
Jens Geyerd629ea02015-09-23 21:16:50 +020056script_dir = os.path.abspath(os.path.dirname(__file__))
57lib_dir = os.path.join(os.path.dirname(os.path.dirname(script_dir)), 'lib', 'py', 'build', 'lib.*')
cdwijayarathna0d4072b2014-08-09 21:32:21 +053058sys.path.insert(0, os.path.join(script_dir, options.genpydir))
Jens Geyerd629ea02015-09-23 21:16:50 +020059sys.path.insert(0, glob.glob(lib_dir)[0])
Roger Meierf4eec7a2011-09-11 18:16:21 +000060
Roger Meier879cab22014-05-03 17:51:21 +020061from ThriftTest import ThriftTest, SecondService
Roger Meierf4eec7a2011-09-11 18:16:21 +000062from ThriftTest.ttypes import *
63from thrift.transport import TTransport
64from thrift.transport import TSocket
65from thrift.transport import THttpClient
66from thrift.transport import TZlibTransport
67from thrift.protocol import TBinaryProtocol
68from thrift.protocol import TCompactProtocol
Roger Meier85fb6de2012-11-02 00:05:42 +000069from thrift.protocol import TJSONProtocol
Roger Meierf4eec7a2011-09-11 18:16:21 +000070
Jens Geyerd629ea02015-09-23 21:16:50 +020071
Mark Slee5299a952007-10-05 00:13:24 +000072class AbstractTest(unittest.TestCase):
Mark Slee5299a952007-10-05 00:13:24 +000073 def setUp(self):
David Reissf78ec2b2009-01-31 21:59:32 +000074 if options.http_path:
Bryan Duxbury16066592011-03-22 18:06:04 +000075 self.transport = THttpClient.THttpClient(options.host, port=options.port, path=options.http_path)
Mark Slee5299a952007-10-05 00:13:24 +000076 else:
Bryan Duxbury16066592011-03-22 18:06:04 +000077 if options.ssl:
78 from thrift.transport import TSSLSocket
79 socket = TSSLSocket.TSSLSocket(options.host, options.port, validate=False)
80 else:
81 socket = TSocket.TSocket(options.host, options.port)
David Reissf78ec2b2009-01-31 21:59:32 +000082 # frame or buffer depending upon args
Roger Meier76150722014-05-31 22:22:07 +020083 self.transport = TTransport.TBufferedTransport(socket)
84 if options.trans == 'framed':
David Reissf78ec2b2009-01-31 21:59:32 +000085 self.transport = TTransport.TFramedTransport(socket)
Roger Meier76150722014-05-31 22:22:07 +020086 elif options.trans == 'buffered':
David Reissf78ec2b2009-01-31 21:59:32 +000087 self.transport = TTransport.TBufferedTransport(socket)
Roger Meier76150722014-05-31 22:22:07 +020088 elif options.trans == '':
89 raise AssertionError('Unknown --transport option: %s' % options.trans)
Bryan Duxbury16066592011-03-22 18:06:04 +000090 if options.zlib:
91 self.transport = TZlibTransport.TZlibTransport(self.transport, 9)
Mark Slee5299a952007-10-05 00:13:24 +000092 self.transport.open()
Mark Slee5299a952007-10-05 00:13:24 +000093 protocol = self.protocol_factory.getProtocol(self.transport)
jfarrelldbf2bb52014-07-09 23:37:12 -040094 self.client = ThriftTest.Client(protocol)
David Reiss0c90f6f2008-02-06 22:18:40 +000095
Mark Slee5299a952007-10-05 00:13:24 +000096 def tearDown(self):
97 # Close!
98 self.transport.close()
Mark Sleefc89d392006-09-04 00:04:39 +000099
Mark Slee5299a952007-10-05 00:13:24 +0000100 def testVoid(self):
Jens Geyerd629ea02015-09-23 21:16:50 +0200101 print('testVoid')
Mark Slee5299a952007-10-05 00:13:24 +0000102 self.client.testVoid()
David Reiss0c90f6f2008-02-06 22:18:40 +0000103
Mark Slee5299a952007-10-05 00:13:24 +0000104 def testString(self):
Jens Geyerd629ea02015-09-23 21:16:50 +0200105 print('testString')
Bryan Duxbury16066592011-03-22 18:06:04 +0000106 self.assertEqual(self.client.testString('Python' * 20), 'Python' * 20)
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000107 self.assertEqual(self.client.testString(''), '')
Mark Sleec9676562006-09-05 17:34:52 +0000108
Nobuaki Sukegawaa649e742015-09-21 13:53:25 +0900109 def testBool(self):
Jens Geyerd629ea02015-09-23 21:16:50 +0200110 print('testBool')
Nobuaki Sukegawaa649e742015-09-21 13:53:25 +0900111 self.assertEqual(self.client.testBool(True), True)
112 self.assertEqual(self.client.testBool(False), False)
113
Mark Slee5299a952007-10-05 00:13:24 +0000114 def testByte(self):
Jens Geyerd629ea02015-09-23 21:16:50 +0200115 print('testByte')
Mark Slee5299a952007-10-05 00:13:24 +0000116 self.assertEqual(self.client.testByte(63), 63)
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000117 self.assertEqual(self.client.testByte(-127), -127)
Mark Sleec98d0502006-09-06 02:42:25 +0000118
Mark Slee5299a952007-10-05 00:13:24 +0000119 def testI32(self):
Jens Geyerd629ea02015-09-23 21:16:50 +0200120 print('testI32')
Mark Slee5299a952007-10-05 00:13:24 +0000121 self.assertEqual(self.client.testI32(-1), -1)
122 self.assertEqual(self.client.testI32(0), 0)
Mark Sleec9676562006-09-05 17:34:52 +0000123
Mark Slee5299a952007-10-05 00:13:24 +0000124 def testI64(self):
Jens Geyerd629ea02015-09-23 21:16:50 +0200125 print('testI64')
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000126 self.assertEqual(self.client.testI64(1), 1)
Mark Slee5299a952007-10-05 00:13:24 +0000127 self.assertEqual(self.client.testI64(-34359738368), -34359738368)
Mark Sleec98d0502006-09-06 02:42:25 +0000128
Mark Slee5299a952007-10-05 00:13:24 +0000129 def testDouble(self):
Jens Geyerd629ea02015-09-23 21:16:50 +0200130 print('testDouble')
Mark Slee5299a952007-10-05 00:13:24 +0000131 self.assertEqual(self.client.testDouble(-5.235098235), -5.235098235)
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000132 self.assertEqual(self.client.testDouble(0), 0)
133 self.assertEqual(self.client.testDouble(-1), -1)
Mark Sleec9676562006-09-05 17:34:52 +0000134
Jens Geyerd629ea02015-09-23 21:16:50 +0200135 def testBinary(self):
136 if isinstance(self, JSONTest):
137 self.skipTest('JSON protocol does not handle binary correctly.')
138 print('testBinary')
139 val = bytearray([i for i in range(0, 256)])
140 self.assertEqual(bytearray(self.client.testBinary(bytes(val))), val)
141
Mark Slee5299a952007-10-05 00:13:24 +0000142 def testStruct(self):
Jens Geyerd629ea02015-09-23 21:16:50 +0200143 print('testStruct')
Mark Slee5299a952007-10-05 00:13:24 +0000144 x = Xtruct()
145 x.string_thing = "Zero"
146 x.byte_thing = 1
147 x.i32_thing = -3
148 x.i64_thing = -5
149 y = self.client.testStruct(x)
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000150 self.assertEqual(y, x)
Mark Sleefc89d392006-09-04 00:04:39 +0000151
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000152 def testNest(self):
Jens Geyerd629ea02015-09-23 21:16:50 +0200153 print('testNest')
154 inner = Xtruct(string_thing="Zero", byte_thing=1, i32_thing=-3, i64_thing=-5)
Roger Meier85fb6de2012-11-02 00:05:42 +0000155 x = Xtruct2(struct_thing=inner, byte_thing=0, i32_thing=0)
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000156 y = self.client.testNest(x)
157 self.assertEqual(y, x)
158
159 def testMap(self):
Jens Geyerd629ea02015-09-23 21:16:50 +0200160 print('testMap')
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000161 x = {0:1, 1:2, 2:3, 3:4, -1:-2}
162 y = self.client.testMap(x)
163 self.assertEqual(y, x)
164
165 def testSet(self):
Jens Geyerd629ea02015-09-23 21:16:50 +0200166 print('testSet')
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000167 x = set([8, 1, 42])
168 y = self.client.testSet(x)
169 self.assertEqual(y, x)
170
171 def testList(self):
Jens Geyerd629ea02015-09-23 21:16:50 +0200172 print('testList')
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000173 x = [1, 4, 9, -42]
174 y = self.client.testList(x)
175 self.assertEqual(y, x)
176
177 def testEnum(self):
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900178 print('testEnum')
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000179 x = Numberz.FIVE
180 y = self.client.testEnum(x)
181 self.assertEqual(y, x)
182
183 def testTypedef(self):
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900184 print('testTypedef')
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000185 x = 0xffffffffffffff # 7 bytes of 0xff
186 y = self.client.testTypedef(x)
187 self.assertEqual(y, x)
188
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900189 @unittest.skip('Cannot use dict as dict key')
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000190 def testMapMap(self):
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900191 print('testMapMap')
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000192 # does not work: dict() is not a hashable type, so a dict() cannot be used as a key in another dict()
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900193 x = {{1: 10, 2: 20}, {1: 100, 2: 200, 3: 300}, {1: 1000, 2: 2000, 3: 3000, 4: 4000}}
194 y = self.client.testMapMap(x)
195 self.assertEqual(y, x)
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000196
197 def testMulti(self):
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900198 print('testMulti')
Roger Meier85fb6de2012-11-02 00:05:42 +0000199 xpected = Xtruct(string_thing='Hello2', byte_thing=74, i32_thing=0xff00ff, i64_thing=0xffffffffd0d0)
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000200 y = self.client.testMulti(xpected.byte_thing,
201 xpected.i32_thing,
202 xpected.i64_thing,
203 { 0:'abc' },
204 Numberz.FIVE,
Roger Meier76150722014-05-31 22:22:07 +0200205 0xf0f0f0)
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000206 self.assertEqual(y, xpected)
Mark Sleec9676562006-09-05 17:34:52 +0000207
Mark Slee5299a952007-10-05 00:13:24 +0000208 def testException(self):
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900209 print('testException')
Mark Slee5299a952007-10-05 00:13:24 +0000210 self.client.testException('Safe')
211 try:
212 self.client.testException('Xception')
213 self.fail("should have gotten exception")
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900214 except Xception as x:
Mark Slee5299a952007-10-05 00:13:24 +0000215 self.assertEqual(x.errorCode, 1001)
216 self.assertEqual(x.message, 'Xception')
Roger Meier61188a42011-11-01 21:03:33 +0000217 # TODO ensure same behavior for repr within generated python variants
Roger Meierf4eec7a2011-09-11 18:16:21 +0000218 # ensure exception's repr method works
Roger Meier61188a42011-11-01 21:03:33 +0000219 #x_repr = repr(x)
220 #self.assertEqual(x_repr, 'Xception(errorCode=1001, message=\'Xception\')')
Mark Sleec9676562006-09-05 17:34:52 +0000221
David Reissbcaa2ad2008-06-10 22:55:26 +0000222 try:
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900223 self.client.testException('TException')
224 self.fail("should have gotten exception")
225 except TException as x:
David Reissbcaa2ad2008-06-10 22:55:26 +0000226 pass
227
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900228 # Should not throw
229 self.client.testException('success')
230
231 def testMultiException(self):
232 print('testMultiException')
233 try:
234 self.client.testMultiException('Xception', 'ignore')
235 except Xception as ex:
236 self.assertEqual(ex.errorCode, 1001)
237 self.assertEqual(ex.message, 'This is an Xception')
238
239 try:
240 self.client.testMultiException('Xception2', 'ignore')
241 except Xception2 as ex:
242 self.assertEqual(ex.errorCode, 2002)
243 self.assertEqual(ex.struct_thing.string_thing, 'This is an Xception2')
244
245 y = self.client.testMultiException('success', 'foobar')
246 self.assertEqual(y.string_thing, 'foobar')
247
David Reiss6ce401d2009-03-24 20:01:58 +0000248 def testOneway(self):
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900249 print('testOneway')
David Reissdb893b62008-02-18 02:11:48 +0000250 start = time.time()
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000251 self.client.testOneway(1) # type is int, not float
David Reissdb893b62008-02-18 02:11:48 +0000252 end = time.time()
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000253 self.assertTrue(end - start < 3,
David Reiss6ce401d2009-03-24 20:01:58 +0000254 "oneway sleep took %f sec" % (end - start))
Roger Meier76150722014-05-31 22:22:07 +0200255
Todd Lipconf5dea4c2009-12-03 01:18:44 +0000256 def testOnewayThenNormal(self):
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900257 print('testOnewayThenNormal')
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000258 self.client.testOneway(1) # type is int, not float
Todd Lipconf5dea4c2009-12-03 01:18:44 +0000259 self.assertEqual(self.client.testString('Python'), 'Python')
David Reissdb893b62008-02-18 02:11:48 +0000260
Roger Meier879cab22014-05-03 17:51:21 +0200261
Mark Slee5299a952007-10-05 00:13:24 +0000262class NormalBinaryTest(AbstractTest):
263 protocol_factory = TBinaryProtocol.TBinaryProtocolFactory()
Mark Sleefc89d392006-09-04 00:04:39 +0000264
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000265class CompactTest(AbstractTest):
266 protocol_factory = TCompactProtocol.TCompactProtocolFactory()
267
Roger Meier85fb6de2012-11-02 00:05:42 +0000268class JSONTest(AbstractTest):
269 protocol_factory = TJSONProtocol.TJSONProtocolFactory()
270
Mark Slee5299a952007-10-05 00:13:24 +0000271class AcceleratedBinaryTest(AbstractTest):
272 protocol_factory = TBinaryProtocol.TBinaryProtocolAcceleratedFactory()
Mark Sleea3302652006-10-25 19:03:32 +0000273
David Reiss9ff3b9d2008-02-15 01:10:23 +0000274def suite():
275 suite = unittest.TestSuite()
276 loader = unittest.TestLoader()
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000277 if options.proto == 'binary': # look for --proto on cmdline
278 suite.addTest(loader.loadTestsFromTestCase(NormalBinaryTest))
279 elif options.proto == 'accel':
280 suite.addTest(loader.loadTestsFromTestCase(AcceleratedBinaryTest))
281 elif options.proto == 'compact':
282 suite.addTest(loader.loadTestsFromTestCase(CompactTest))
Roger Meier85fb6de2012-11-02 00:05:42 +0000283 elif options.proto == 'json':
284 suite.addTest(loader.loadTestsFromTestCase(JSONTest))
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000285 else:
Roger Meier76150722014-05-31 22:22:07 +0200286 raise AssertionError('Unknown protocol given with --protocol: %s' % options.proto)
David Reiss9ff3b9d2008-02-15 01:10:23 +0000287 return suite
Mark Slee5299a952007-10-05 00:13:24 +0000288
David Reiss74421272008-11-07 23:09:31 +0000289class OwnArgsTestProgram(unittest.TestProgram):
290 def parseArgs(self, argv):
291 if args:
292 self.testNames = args
293 else:
294 self.testNames = (self.defaultTest,)
295 self.createTests()
296
David Reiss9ff3b9d2008-02-15 01:10:23 +0000297if __name__ == "__main__":
Roger Meierf4eec7a2011-09-11 18:16:21 +0000298 OwnArgsTestProgram(defaultTest="suite", testRunner=unittest.TextTestRunner(verbosity=1))