blob: 7e3daf2676e5cf01a79a25bdf523e1139c3a54cf [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)
Mark Sleec9676562006-09-05 17:34:52 +0000161
Jens Geyerd629ea02015-09-23 21:16:50 +0200162 def testBinary(self):
163 if isinstance(self, JSONTest):
164 self.skipTest('JSON protocol does not handle binary correctly.')
165 print('testBinary')
166 val = bytearray([i for i in range(0, 256)])
167 self.assertEqual(bytearray(self.client.testBinary(bytes(val))), val)
168
Mark Slee5299a952007-10-05 00:13:24 +0000169 def testStruct(self):
Jens Geyerd629ea02015-09-23 21:16:50 +0200170 print('testStruct')
Mark Slee5299a952007-10-05 00:13:24 +0000171 x = Xtruct()
172 x.string_thing = "Zero"
173 x.byte_thing = 1
174 x.i32_thing = -3
175 x.i64_thing = -5
176 y = self.client.testStruct(x)
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000177 self.assertEqual(y, x)
Mark Sleefc89d392006-09-04 00:04:39 +0000178
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000179 def testNest(self):
Jens Geyerd629ea02015-09-23 21:16:50 +0200180 print('testNest')
181 inner = Xtruct(string_thing="Zero", byte_thing=1, i32_thing=-3, i64_thing=-5)
Roger Meier85fb6de2012-11-02 00:05:42 +0000182 x = Xtruct2(struct_thing=inner, byte_thing=0, i32_thing=0)
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000183 y = self.client.testNest(x)
184 self.assertEqual(y, x)
185
186 def testMap(self):
Jens Geyerd629ea02015-09-23 21:16:50 +0200187 print('testMap')
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000188 x = {0:1, 1:2, 2:3, 3:4, -1:-2}
189 y = self.client.testMap(x)
190 self.assertEqual(y, x)
191
192 def testSet(self):
Jens Geyerd629ea02015-09-23 21:16:50 +0200193 print('testSet')
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000194 x = set([8, 1, 42])
195 y = self.client.testSet(x)
196 self.assertEqual(y, x)
197
198 def testList(self):
Jens Geyerd629ea02015-09-23 21:16:50 +0200199 print('testList')
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000200 x = [1, 4, 9, -42]
201 y = self.client.testList(x)
202 self.assertEqual(y, x)
203
204 def testEnum(self):
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900205 print('testEnum')
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000206 x = Numberz.FIVE
207 y = self.client.testEnum(x)
208 self.assertEqual(y, x)
209
210 def testTypedef(self):
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900211 print('testTypedef')
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000212 x = 0xffffffffffffff # 7 bytes of 0xff
213 y = self.client.testTypedef(x)
214 self.assertEqual(y, x)
215
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900216 @unittest.skip('Cannot use dict as dict key')
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000217 def testMapMap(self):
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900218 print('testMapMap')
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000219 # 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 +0900220 x = {{1: 10, 2: 20}, {1: 100, 2: 200, 3: 300}, {1: 1000, 2: 2000, 3: 3000, 4: 4000}}
221 y = self.client.testMapMap(x)
222 self.assertEqual(y, x)
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000223
224 def testMulti(self):
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900225 print('testMulti')
Roger Meier85fb6de2012-11-02 00:05:42 +0000226 xpected = Xtruct(string_thing='Hello2', byte_thing=74, i32_thing=0xff00ff, i64_thing=0xffffffffd0d0)
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000227 y = self.client.testMulti(xpected.byte_thing,
228 xpected.i32_thing,
229 xpected.i64_thing,
230 { 0:'abc' },
231 Numberz.FIVE,
Roger Meier76150722014-05-31 22:22:07 +0200232 0xf0f0f0)
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000233 self.assertEqual(y, xpected)
Mark Sleec9676562006-09-05 17:34:52 +0000234
Mark Slee5299a952007-10-05 00:13:24 +0000235 def testException(self):
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900236 print('testException')
Mark Slee5299a952007-10-05 00:13:24 +0000237 self.client.testException('Safe')
238 try:
239 self.client.testException('Xception')
240 self.fail("should have gotten exception")
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900241 except Xception as x:
Mark Slee5299a952007-10-05 00:13:24 +0000242 self.assertEqual(x.errorCode, 1001)
243 self.assertEqual(x.message, 'Xception')
Roger Meier61188a42011-11-01 21:03:33 +0000244 # TODO ensure same behavior for repr within generated python variants
Roger Meierf4eec7a2011-09-11 18:16:21 +0000245 # ensure exception's repr method works
Roger Meier61188a42011-11-01 21:03:33 +0000246 #x_repr = repr(x)
247 #self.assertEqual(x_repr, 'Xception(errorCode=1001, message=\'Xception\')')
Mark Sleec9676562006-09-05 17:34:52 +0000248
David Reissbcaa2ad2008-06-10 22:55:26 +0000249 try:
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900250 self.client.testException('TException')
251 self.fail("should have gotten exception")
252 except TException as x:
David Reissbcaa2ad2008-06-10 22:55:26 +0000253 pass
254
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900255 # Should not throw
256 self.client.testException('success')
257
258 def testMultiException(self):
259 print('testMultiException')
260 try:
261 self.client.testMultiException('Xception', 'ignore')
262 except Xception as ex:
263 self.assertEqual(ex.errorCode, 1001)
264 self.assertEqual(ex.message, 'This is an Xception')
265
266 try:
267 self.client.testMultiException('Xception2', 'ignore')
268 except Xception2 as ex:
269 self.assertEqual(ex.errorCode, 2002)
270 self.assertEqual(ex.struct_thing.string_thing, 'This is an Xception2')
271
272 y = self.client.testMultiException('success', 'foobar')
273 self.assertEqual(y.string_thing, 'foobar')
274
David Reiss6ce401d2009-03-24 20:01:58 +0000275 def testOneway(self):
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900276 print('testOneway')
David Reissdb893b62008-02-18 02:11:48 +0000277 start = time.time()
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000278 self.client.testOneway(1) # type is int, not float
David Reissdb893b62008-02-18 02:11:48 +0000279 end = time.time()
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000280 self.assertTrue(end - start < 3,
David Reiss6ce401d2009-03-24 20:01:58 +0000281 "oneway sleep took %f sec" % (end - start))
Roger Meier76150722014-05-31 22:22:07 +0200282
Todd Lipconf5dea4c2009-12-03 01:18:44 +0000283 def testOnewayThenNormal(self):
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900284 print('testOnewayThenNormal')
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000285 self.client.testOneway(1) # type is int, not float
Todd Lipconf5dea4c2009-12-03 01:18:44 +0000286 self.assertEqual(self.client.testString('Python'), 'Python')
David Reissdb893b62008-02-18 02:11:48 +0000287
Roger Meier879cab22014-05-03 17:51:21 +0200288
Mark Slee5299a952007-10-05 00:13:24 +0000289class NormalBinaryTest(AbstractTest):
290 protocol_factory = TBinaryProtocol.TBinaryProtocolFactory()
Mark Sleefc89d392006-09-04 00:04:39 +0000291
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000292class CompactTest(AbstractTest):
293 protocol_factory = TCompactProtocol.TCompactProtocolFactory()
294
Roger Meier85fb6de2012-11-02 00:05:42 +0000295class JSONTest(AbstractTest):
296 protocol_factory = TJSONProtocol.TJSONProtocolFactory()
297
Mark Slee5299a952007-10-05 00:13:24 +0000298class AcceleratedBinaryTest(AbstractTest):
299 protocol_factory = TBinaryProtocol.TBinaryProtocolAcceleratedFactory()
Mark Sleea3302652006-10-25 19:03:32 +0000300
David Reiss9ff3b9d2008-02-15 01:10:23 +0000301def suite():
302 suite = unittest.TestSuite()
303 loader = unittest.TestLoader()
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000304 if options.proto == 'binary': # look for --proto on cmdline
305 suite.addTest(loader.loadTestsFromTestCase(NormalBinaryTest))
306 elif options.proto == 'accel':
307 suite.addTest(loader.loadTestsFromTestCase(AcceleratedBinaryTest))
308 elif options.proto == 'compact':
309 suite.addTest(loader.loadTestsFromTestCase(CompactTest))
Roger Meier85fb6de2012-11-02 00:05:42 +0000310 elif options.proto == 'json':
311 suite.addTest(loader.loadTestsFromTestCase(JSONTest))
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000312 else:
Roger Meier76150722014-05-31 22:22:07 +0200313 raise AssertionError('Unknown protocol given with --protocol: %s' % options.proto)
David Reiss9ff3b9d2008-02-15 01:10:23 +0000314 return suite
Mark Slee5299a952007-10-05 00:13:24 +0000315
David Reiss74421272008-11-07 23:09:31 +0000316class OwnArgsTestProgram(unittest.TestProgram):
317 def parseArgs(self, argv):
318 if args:
319 self.testNames = args
320 else:
321 self.testNames = (self.defaultTest,)
322 self.createTests()
323
David Reiss9ff3b9d2008-02-15 01:10:23 +0000324if __name__ == "__main__":
Roger Meierf4eec7a2011-09-11 18:16:21 +0000325 OwnArgsTestProgram(defaultTest="suite", testRunner=unittest.TextTestRunner(verbosity=1))