blob: 3a74353f7dc682078333695b233e73056289a137 [file] [log] [blame]
Mark Slee57cc25e2007-02-28 21:43:54 +00001#!/usr/bin/env python
Nobuaki Sukegawa64b8f6c2015-10-10 02:12:48 +09002# -*- coding: utf-8 -*-
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(''), '')
Nobuaki Sukegawa64b8f6c2015-10-10 02:12:48 +0900108 self.assertEqual(self.client.testString(u'パイソン'.encode('utf8')), u'パイソン'.encode('utf8'))
109 s = u"""Afrikaans, Alemannisch, Aragonés, العربية, مصرى,
110 Asturianu, Aymar aru, Azərbaycan, Башҡорт, Boarisch, Žemaitėška,
111 Беларуская, Беларуская (тарашкевіца), Български, Bamanankan,
112 বাংলা, Brezhoneg, Bosanski, Català, Mìng-dĕ̤ng-ngṳ̄, Нохчийн,
113 Cebuano, ᏣᎳᎩ, Česky, Словѣ́ньскъ / ⰔⰎⰑⰂⰡⰐⰠⰔⰍⰟ, Чӑвашла, Cymraeg,
114 Dansk, Zazaki, ދިވެހިބަސް, Ελληνικά, Emiliàn e rumagnòl, English,
115 Esperanto, Español, Eesti, Euskara, فارسی, Suomi, Võro, Føroyskt,
116 Français, Arpetan, Furlan, Frysk, Gaeilge, 贛語, Gàidhlig, Galego,
117 Avañe'ẽ, ગુજરાતી, Gaelg, עברית, हिन्दी, Fiji Hindi, Hrvatski,
118 Kreyòl ayisyen, Magyar, Հայերեն, Interlingua, Bahasa Indonesia,
119 Ilokano, Ido, Íslenska, Italiano, 日本語, Lojban, Basa Jawa,
120 ქართული, Kongo, Kalaallisut, ಕನ್ನಡ, 한국어, Къарачай-Малкъар,
121 Ripoarisch, Kurdî, Коми, Kernewek, Кыргызча, Latina, Ladino,
122 Lëtzebuergesch, Limburgs, Lingála, ລາວ, Lietuvių, Latviešu, Basa
123 Banyumasan, Malagasy, Македонски, മലയാളം, मराठी, مازِرونی, Bahasa
124 Melayu, Nnapulitano, Nedersaksisch, नेपाल भाषा, Nederlands, ‪
125 Norsk (nynorsk)‬, ‪Norsk (bokmål)‬, Nouormand, Diné bizaad,
126 Occitan, Иронау, Papiamentu, Deitsch, Polski, پنجابی, پښتو,
127 Norfuk / Pitkern, Português, Runa Simi, Rumantsch, Romani, Română,
128 Русский, Саха тыла, Sardu, Sicilianu, Scots, Sámegiella, Simple
129 English, Slovenčina, Slovenščina, Српски / Srpski, Seeltersk,
130 Svenska, Kiswahili, தமிழ், తెలుగు, Тоҷикӣ, ไทย, Türkmençe, Tagalog,
131 Türkçe, Татарча/Tatarça, Українська, اردو, Tiếng Việt, Volapük,
132 Walon, Winaray, 吴语, isiXhosa, ייִדיש, Yorùbá, Zeêuws, 中文,
133 Bân-lâm-gú, 粵語"""
134 self.assertEqual(self.client.testString(s.encode('utf8')), s.encode('utf8'))
Mark Sleec9676562006-09-05 17:34:52 +0000135
Nobuaki Sukegawaa649e742015-09-21 13:53:25 +0900136 def testBool(self):
Jens Geyerd629ea02015-09-23 21:16:50 +0200137 print('testBool')
Nobuaki Sukegawaa649e742015-09-21 13:53:25 +0900138 self.assertEqual(self.client.testBool(True), True)
139 self.assertEqual(self.client.testBool(False), False)
140
Mark Slee5299a952007-10-05 00:13:24 +0000141 def testByte(self):
Jens Geyerd629ea02015-09-23 21:16:50 +0200142 print('testByte')
Mark Slee5299a952007-10-05 00:13:24 +0000143 self.assertEqual(self.client.testByte(63), 63)
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000144 self.assertEqual(self.client.testByte(-127), -127)
Mark Sleec98d0502006-09-06 02:42:25 +0000145
Mark Slee5299a952007-10-05 00:13:24 +0000146 def testI32(self):
Jens Geyerd629ea02015-09-23 21:16:50 +0200147 print('testI32')
Mark Slee5299a952007-10-05 00:13:24 +0000148 self.assertEqual(self.client.testI32(-1), -1)
149 self.assertEqual(self.client.testI32(0), 0)
Mark Sleec9676562006-09-05 17:34:52 +0000150
Mark Slee5299a952007-10-05 00:13:24 +0000151 def testI64(self):
Jens Geyerd629ea02015-09-23 21:16:50 +0200152 print('testI64')
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000153 self.assertEqual(self.client.testI64(1), 1)
Mark Slee5299a952007-10-05 00:13:24 +0000154 self.assertEqual(self.client.testI64(-34359738368), -34359738368)
Mark Sleec98d0502006-09-06 02:42:25 +0000155
Mark Slee5299a952007-10-05 00:13:24 +0000156 def testDouble(self):
Jens Geyerd629ea02015-09-23 21:16:50 +0200157 print('testDouble')
Mark Slee5299a952007-10-05 00:13:24 +0000158 self.assertEqual(self.client.testDouble(-5.235098235), -5.235098235)
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000159 self.assertEqual(self.client.testDouble(0), 0)
160 self.assertEqual(self.client.testDouble(-1), -1)
Nobuaki Sukegawa228b3282015-10-10 03:11:49 +0900161 self.assertEqual(self.client.testDouble(-0.000341012439638598279), -0.000341012439638598279)
Mark Sleec9676562006-09-05 17:34:52 +0000162
Jens Geyerd629ea02015-09-23 21:16:50 +0200163 def testBinary(self):
164 if isinstance(self, JSONTest):
165 self.skipTest('JSON protocol does not handle binary correctly.')
166 print('testBinary')
167 val = bytearray([i for i in range(0, 256)])
168 self.assertEqual(bytearray(self.client.testBinary(bytes(val))), val)
169
Mark Slee5299a952007-10-05 00:13:24 +0000170 def testStruct(self):
Jens Geyerd629ea02015-09-23 21:16:50 +0200171 print('testStruct')
Mark Slee5299a952007-10-05 00:13:24 +0000172 x = Xtruct()
173 x.string_thing = "Zero"
174 x.byte_thing = 1
175 x.i32_thing = -3
176 x.i64_thing = -5
177 y = self.client.testStruct(x)
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000178 self.assertEqual(y, x)
Mark Sleefc89d392006-09-04 00:04:39 +0000179
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000180 def testNest(self):
Jens Geyerd629ea02015-09-23 21:16:50 +0200181 print('testNest')
182 inner = Xtruct(string_thing="Zero", byte_thing=1, i32_thing=-3, i64_thing=-5)
Roger Meier85fb6de2012-11-02 00:05:42 +0000183 x = Xtruct2(struct_thing=inner, byte_thing=0, i32_thing=0)
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000184 y = self.client.testNest(x)
185 self.assertEqual(y, x)
186
187 def testMap(self):
Jens Geyerd629ea02015-09-23 21:16:50 +0200188 print('testMap')
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000189 x = {0:1, 1:2, 2:3, 3:4, -1:-2}
190 y = self.client.testMap(x)
191 self.assertEqual(y, x)
192
193 def testSet(self):
Jens Geyerd629ea02015-09-23 21:16:50 +0200194 print('testSet')
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000195 x = set([8, 1, 42])
196 y = self.client.testSet(x)
197 self.assertEqual(y, x)
198
199 def testList(self):
Jens Geyerd629ea02015-09-23 21:16:50 +0200200 print('testList')
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000201 x = [1, 4, 9, -42]
202 y = self.client.testList(x)
203 self.assertEqual(y, x)
204
205 def testEnum(self):
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900206 print('testEnum')
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000207 x = Numberz.FIVE
208 y = self.client.testEnum(x)
209 self.assertEqual(y, x)
210
211 def testTypedef(self):
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900212 print('testTypedef')
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000213 x = 0xffffffffffffff # 7 bytes of 0xff
214 y = self.client.testTypedef(x)
215 self.assertEqual(y, x)
216
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900217 @unittest.skip('Cannot use dict as dict key')
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000218 def testMapMap(self):
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900219 print('testMapMap')
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000220 # 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 +0900221 x = {{1: 10, 2: 20}, {1: 100, 2: 200, 3: 300}, {1: 1000, 2: 2000, 3: 3000, 4: 4000}}
222 y = self.client.testMapMap(x)
223 self.assertEqual(y, x)
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000224
225 def testMulti(self):
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900226 print('testMulti')
Roger Meier85fb6de2012-11-02 00:05:42 +0000227 xpected = Xtruct(string_thing='Hello2', byte_thing=74, i32_thing=0xff00ff, i64_thing=0xffffffffd0d0)
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000228 y = self.client.testMulti(xpected.byte_thing,
229 xpected.i32_thing,
230 xpected.i64_thing,
231 { 0:'abc' },
232 Numberz.FIVE,
Roger Meier76150722014-05-31 22:22:07 +0200233 0xf0f0f0)
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000234 self.assertEqual(y, xpected)
Mark Sleec9676562006-09-05 17:34:52 +0000235
Mark Slee5299a952007-10-05 00:13:24 +0000236 def testException(self):
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900237 print('testException')
Mark Slee5299a952007-10-05 00:13:24 +0000238 self.client.testException('Safe')
239 try:
240 self.client.testException('Xception')
241 self.fail("should have gotten exception")
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900242 except Xception as x:
Mark Slee5299a952007-10-05 00:13:24 +0000243 self.assertEqual(x.errorCode, 1001)
244 self.assertEqual(x.message, 'Xception')
Roger Meier61188a42011-11-01 21:03:33 +0000245 # TODO ensure same behavior for repr within generated python variants
Roger Meierf4eec7a2011-09-11 18:16:21 +0000246 # ensure exception's repr method works
Roger Meier61188a42011-11-01 21:03:33 +0000247 #x_repr = repr(x)
248 #self.assertEqual(x_repr, 'Xception(errorCode=1001, message=\'Xception\')')
Mark Sleec9676562006-09-05 17:34:52 +0000249
David Reissbcaa2ad2008-06-10 22:55:26 +0000250 try:
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900251 self.client.testException('TException')
252 self.fail("should have gotten exception")
253 except TException as x:
David Reissbcaa2ad2008-06-10 22:55:26 +0000254 pass
255
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900256 # Should not throw
257 self.client.testException('success')
258
259 def testMultiException(self):
260 print('testMultiException')
261 try:
262 self.client.testMultiException('Xception', 'ignore')
263 except Xception as ex:
264 self.assertEqual(ex.errorCode, 1001)
265 self.assertEqual(ex.message, 'This is an Xception')
266
267 try:
268 self.client.testMultiException('Xception2', 'ignore')
269 except Xception2 as ex:
270 self.assertEqual(ex.errorCode, 2002)
271 self.assertEqual(ex.struct_thing.string_thing, 'This is an Xception2')
272
273 y = self.client.testMultiException('success', 'foobar')
274 self.assertEqual(y.string_thing, 'foobar')
275
David Reiss6ce401d2009-03-24 20:01:58 +0000276 def testOneway(self):
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900277 print('testOneway')
David Reissdb893b62008-02-18 02:11:48 +0000278 start = time.time()
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000279 self.client.testOneway(1) # type is int, not float
David Reissdb893b62008-02-18 02:11:48 +0000280 end = time.time()
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000281 self.assertTrue(end - start < 3,
David Reiss6ce401d2009-03-24 20:01:58 +0000282 "oneway sleep took %f sec" % (end - start))
Roger Meier76150722014-05-31 22:22:07 +0200283
Todd Lipconf5dea4c2009-12-03 01:18:44 +0000284 def testOnewayThenNormal(self):
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900285 print('testOnewayThenNormal')
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000286 self.client.testOneway(1) # type is int, not float
Todd Lipconf5dea4c2009-12-03 01:18:44 +0000287 self.assertEqual(self.client.testString('Python'), 'Python')
David Reissdb893b62008-02-18 02:11:48 +0000288
Roger Meier879cab22014-05-03 17:51:21 +0200289
Mark Slee5299a952007-10-05 00:13:24 +0000290class NormalBinaryTest(AbstractTest):
291 protocol_factory = TBinaryProtocol.TBinaryProtocolFactory()
Mark Sleefc89d392006-09-04 00:04:39 +0000292
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000293class CompactTest(AbstractTest):
294 protocol_factory = TCompactProtocol.TCompactProtocolFactory()
295
Roger Meier85fb6de2012-11-02 00:05:42 +0000296class JSONTest(AbstractTest):
297 protocol_factory = TJSONProtocol.TJSONProtocolFactory()
298
Mark Slee5299a952007-10-05 00:13:24 +0000299class AcceleratedBinaryTest(AbstractTest):
300 protocol_factory = TBinaryProtocol.TBinaryProtocolAcceleratedFactory()
Mark Sleea3302652006-10-25 19:03:32 +0000301
David Reiss9ff3b9d2008-02-15 01:10:23 +0000302def suite():
303 suite = unittest.TestSuite()
304 loader = unittest.TestLoader()
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000305 if options.proto == 'binary': # look for --proto on cmdline
306 suite.addTest(loader.loadTestsFromTestCase(NormalBinaryTest))
307 elif options.proto == 'accel':
308 suite.addTest(loader.loadTestsFromTestCase(AcceleratedBinaryTest))
309 elif options.proto == 'compact':
310 suite.addTest(loader.loadTestsFromTestCase(CompactTest))
Roger Meier85fb6de2012-11-02 00:05:42 +0000311 elif options.proto == 'json':
312 suite.addTest(loader.loadTestsFromTestCase(JSONTest))
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000313 else:
Roger Meier76150722014-05-31 22:22:07 +0200314 raise AssertionError('Unknown protocol given with --protocol: %s' % options.proto)
David Reiss9ff3b9d2008-02-15 01:10:23 +0000315 return suite
Mark Slee5299a952007-10-05 00:13:24 +0000316
David Reiss74421272008-11-07 23:09:31 +0000317class OwnArgsTestProgram(unittest.TestProgram):
318 def parseArgs(self, argv):
319 if args:
320 self.testNames = args
321 else:
322 self.testNames = (self.defaultTest,)
323 self.createTests()
324
David Reiss9ff3b9d2008-02-15 01:10:23 +0000325if __name__ == "__main__":
Roger Meierf4eec7a2011-09-11 18:16:21 +0000326 OwnArgsTestProgram(defaultTest="suite", testRunner=unittest.TextTestRunner(verbosity=1))