blob: 18ef66bb77823aeedf0516ed604d856d8bcd2115 [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 os
23import sys
Mark Slee57cc25e2007-02-28 21:43:54 +000024import time
Jens Geyerd629ea02015-09-23 21:16:50 +020025import unittest
Mark Slee5299a952007-10-05 00:13:24 +000026from optparse import OptionParser
Mark Slee57cc25e2007-02-28 21:43:54 +000027
Nobuaki Sukegawa7af189a2016-02-11 16:21:01 +090028from util import local_libpath
29
Nobuaki Sukegawaa185d7e2015-11-06 21:24:24 +090030SCRIPT_DIR = os.path.abspath(os.path.dirname(__file__))
Roger Meierf4eec7a2011-09-11 18:16:21 +000031
Jens Geyerd629ea02015-09-23 21:16:50 +020032
Mark Slee5299a952007-10-05 00:13:24 +000033class AbstractTest(unittest.TestCase):
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090034 def setUp(self):
35 if options.http_path:
36 self.transport = THttpClient.THttpClient(options.host, port=options.port, path=options.http_path)
37 else:
38 if options.ssl:
39 from thrift.transport import TSSLSocket
40 socket = TSSLSocket.TSSLSocket(options.host, options.port, validate=False)
41 else:
42 socket = TSocket.TSocket(options.host, options.port)
43 # frame or buffer depending upon args
44 self.transport = TTransport.TBufferedTransport(socket)
45 if options.trans == 'framed':
46 self.transport = TTransport.TFramedTransport(socket)
47 elif options.trans == 'buffered':
48 self.transport = TTransport.TBufferedTransport(socket)
49 elif options.trans == '':
50 raise AssertionError('Unknown --transport option: %s' % options.trans)
51 if options.zlib:
52 self.transport = TZlibTransport.TZlibTransport(self.transport, 9)
53 self.transport.open()
54 protocol = self.get_protocol(self.transport)
55 self.client = ThriftTest.Client(protocol)
David Reiss0c90f6f2008-02-06 22:18:40 +000056
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090057 def tearDown(self):
58 self.transport.close()
Mark Sleefc89d392006-09-04 00:04:39 +000059
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090060 def testVoid(self):
61 print('testVoid')
62 self.client.testVoid()
David Reiss0c90f6f2008-02-06 22:18:40 +000063
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090064 def testString(self):
65 print('testString')
66 self.assertEqual(self.client.testString('Python' * 20), 'Python' * 20)
67 self.assertEqual(self.client.testString(''), '')
68 s1 = u'\b\t\n/\\\\\r{}:パイソン"'
69 s2 = u"""Afrikaans, Alemannisch, Aragonés, العربية, مصرى,
Nobuaki Sukegawa64b8f6c2015-10-10 02:12:48 +090070 Asturianu, Aymar aru, Azərbaycan, Башҡорт, Boarisch, Žemaitėška,
71 Беларуская, Беларуская (тарашкевіца), Български, Bamanankan,
72 বাংলা, Brezhoneg, Bosanski, Català, Mìng-dĕ̤ng-ngṳ̄, Нохчийн,
73 Cebuano, ᏣᎳᎩ, Česky, Словѣ́ньскъ / ⰔⰎⰑⰂⰡⰐⰠⰔⰍⰟ, Чӑвашла, Cymraeg,
74 Dansk, Zazaki, ދިވެހިބަސް, Ελληνικά, Emiliàn e rumagnòl, English,
75 Esperanto, Español, Eesti, Euskara, فارسی, Suomi, Võro, Føroyskt,
76 Français, Arpetan, Furlan, Frysk, Gaeilge, 贛語, Gàidhlig, Galego,
77 Avañe'ẽ, ગુજરાતી, Gaelg, עברית, हिन्दी, Fiji Hindi, Hrvatski,
78 Kreyòl ayisyen, Magyar, Հայերեն, Interlingua, Bahasa Indonesia,
79 Ilokano, Ido, Íslenska, Italiano, 日本語, Lojban, Basa Jawa,
80 ქართული, Kongo, Kalaallisut, ಕನ್ನಡ, 한국어, Къарачай-Малкъар,
81 Ripoarisch, Kurdî, Коми, Kernewek, Кыргызча, Latina, Ladino,
82 Lëtzebuergesch, Limburgs, Lingála, ລາວ, Lietuvių, Latviešu, Basa
83 Banyumasan, Malagasy, Македонски, മലയാളം, मराठी, مازِرونی, Bahasa
84 Melayu, Nnapulitano, Nedersaksisch, नेपाल भाषा, Nederlands, ‪
85 Norsk (nynorsk)‬, ‪Norsk (bokmål)‬, Nouormand, Diné bizaad,
86 Occitan, Иронау, Papiamentu, Deitsch, Polski, پنجابی, پښتو,
87 Norfuk / Pitkern, Português, Runa Simi, Rumantsch, Romani, Română,
88 Русский, Саха тыла, Sardu, Sicilianu, Scots, Sámegiella, Simple
89 English, Slovenčina, Slovenščina, Српски / Srpski, Seeltersk,
90 Svenska, Kiswahili, தமிழ், తెలుగు, Тоҷикӣ, ไทย, Türkmençe, Tagalog,
91 Türkçe, Татарча/Tatarça, Українська, اردو, Tiếng Việt, Volapük,
92 Walon, Winaray, 吴语, isiXhosa, ייִדיש, Yorùbá, Zeêuws, 中文,
93 Bân-lâm-gú, 粵語"""
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090094 if sys.version_info[0] == 2 and os.environ.get('THRIFT_TEST_PY_NO_UTF8STRINGS'):
95 s1 = s1.encode('utf8')
96 s2 = s2.encode('utf8')
97 self.assertEqual(self.client.testString(s1), s1)
98 self.assertEqual(self.client.testString(s2), s2)
Mark Sleec9676562006-09-05 17:34:52 +000099
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900100 def testBool(self):
101 print('testBool')
102 self.assertEqual(self.client.testBool(True), True)
103 self.assertEqual(self.client.testBool(False), False)
Nobuaki Sukegawaa649e742015-09-21 13:53:25 +0900104
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900105 def testByte(self):
106 print('testByte')
107 self.assertEqual(self.client.testByte(63), 63)
108 self.assertEqual(self.client.testByte(-127), -127)
Mark Sleec98d0502006-09-06 02:42:25 +0000109
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900110 def testI32(self):
111 print('testI32')
112 self.assertEqual(self.client.testI32(-1), -1)
113 self.assertEqual(self.client.testI32(0), 0)
Mark Sleec9676562006-09-05 17:34:52 +0000114
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900115 def testI64(self):
116 print('testI64')
117 self.assertEqual(self.client.testI64(1), 1)
118 self.assertEqual(self.client.testI64(-34359738368), -34359738368)
Mark Sleec98d0502006-09-06 02:42:25 +0000119
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900120 def testDouble(self):
121 print('testDouble')
122 self.assertEqual(self.client.testDouble(-5.235098235), -5.235098235)
123 self.assertEqual(self.client.testDouble(0), 0)
124 self.assertEqual(self.client.testDouble(-1), -1)
125 self.assertEqual(self.client.testDouble(-0.000341012439638598279), -0.000341012439638598279)
Mark Sleec9676562006-09-05 17:34:52 +0000126
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900127 def testBinary(self):
128 print('testBinary')
129 val = bytearray([i for i in range(0, 256)])
130 self.assertEqual(bytearray(self.client.testBinary(bytes(val))), val)
Jens Geyerd629ea02015-09-23 21:16:50 +0200131
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900132 def testStruct(self):
133 print('testStruct')
134 x = Xtruct()
135 x.string_thing = "Zero"
136 x.byte_thing = 1
137 x.i32_thing = -3
138 x.i64_thing = -5
139 y = self.client.testStruct(x)
140 self.assertEqual(y, x)
Mark Sleefc89d392006-09-04 00:04:39 +0000141
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900142 def testNest(self):
143 print('testNest')
144 inner = Xtruct(string_thing="Zero", byte_thing=1, i32_thing=-3, i64_thing=-5)
145 x = Xtruct2(struct_thing=inner, byte_thing=0, i32_thing=0)
146 y = self.client.testNest(x)
147 self.assertEqual(y, x)
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000148
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900149 def testMap(self):
150 print('testMap')
151 x = {0: 1, 1: 2, 2: 3, 3: 4, -1: -2}
152 y = self.client.testMap(x)
153 self.assertEqual(y, x)
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000154
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900155 def testSet(self):
156 print('testSet')
157 x = set([8, 1, 42])
158 y = self.client.testSet(x)
159 self.assertEqual(y, x)
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000160
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900161 def testList(self):
162 print('testList')
163 x = [1, 4, 9, -42]
164 y = self.client.testList(x)
165 self.assertEqual(y, x)
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000166
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900167 def testEnum(self):
168 print('testEnum')
169 x = Numberz.FIVE
170 y = self.client.testEnum(x)
171 self.assertEqual(y, x)
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000172
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900173 def testTypedef(self):
174 print('testTypedef')
175 x = 0xffffffffffffff # 7 bytes of 0xff
176 y = self.client.testTypedef(x)
177 self.assertEqual(y, x)
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000178
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900179 def testMapMap(self):
180 print('testMapMap')
181 x = {
182 -4: {-4: -4, -3: -3, -2: -2, -1: -1},
183 4: {4: 4, 3: 3, 2: 2, 1: 1},
184 }
185 y = self.client.testMapMap(42)
186 self.assertEqual(y, x)
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000187
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900188 def testMulti(self):
189 print('testMulti')
190 xpected = Xtruct(string_thing='Hello2', byte_thing=74, i32_thing=0xff00ff, i64_thing=0xffffffffd0d0)
191 y = self.client.testMulti(xpected.byte_thing,
192 xpected.i32_thing,
193 xpected.i64_thing,
194 {0: 'abc'},
195 Numberz.FIVE,
196 0xf0f0f0)
197 self.assertEqual(y, xpected)
Mark Sleec9676562006-09-05 17:34:52 +0000198
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900199 def testException(self):
200 print('testException')
201 self.client.testException('Safe')
202 try:
203 self.client.testException('Xception')
204 self.fail("should have gotten exception")
205 except Xception as x:
206 self.assertEqual(x.errorCode, 1001)
207 self.assertEqual(x.message, 'Xception')
208 # TODO ensure same behavior for repr within generated python variants
209 # ensure exception's repr method works
210 # x_repr = repr(x)
211 # self.assertEqual(x_repr, 'Xception(errorCode=1001, message=\'Xception\')')
Mark Sleec9676562006-09-05 17:34:52 +0000212
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900213 try:
214 self.client.testException('TException')
215 self.fail("should have gotten exception")
216 except TException as x:
217 pass
David Reissbcaa2ad2008-06-10 22:55:26 +0000218
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900219 # Should not throw
220 self.client.testException('success')
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900221
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900222 def testMultiException(self):
223 print('testMultiException')
224 try:
225 self.client.testMultiException('Xception', 'ignore')
226 except Xception as ex:
227 self.assertEqual(ex.errorCode, 1001)
228 self.assertEqual(ex.message, 'This is an Xception')
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900229
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900230 try:
231 self.client.testMultiException('Xception2', 'ignore')
232 except Xception2 as ex:
233 self.assertEqual(ex.errorCode, 2002)
234 self.assertEqual(ex.struct_thing.string_thing, 'This is an Xception2')
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900235
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900236 y = self.client.testMultiException('success', 'foobar')
237 self.assertEqual(y.string_thing, 'foobar')
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900238
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900239 def testOneway(self):
240 print('testOneway')
241 start = time.time()
242 self.client.testOneway(1) # type is int, not float
243 end = time.time()
244 self.assertTrue(end - start < 3,
245 "oneway sleep took %f sec" % (end - start))
Roger Meier76150722014-05-31 22:22:07 +0200246
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900247 def testOnewayThenNormal(self):
248 print('testOnewayThenNormal')
249 self.client.testOneway(1) # type is int, not float
250 self.assertEqual(self.client.testString('Python'), 'Python')
David Reissdb893b62008-02-18 02:11:48 +0000251
Roger Meier879cab22014-05-03 17:51:21 +0200252
Mark Slee5299a952007-10-05 00:13:24 +0000253class NormalBinaryTest(AbstractTest):
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900254 def get_protocol(self, transport):
255 return TBinaryProtocol.TBinaryProtocolFactory().getProtocol(transport)
Mark Sleefc89d392006-09-04 00:04:39 +0000256
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900257
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000258class CompactTest(AbstractTest):
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900259 def get_protocol(self, transport):
260 return TCompactProtocol.TCompactProtocolFactory().getProtocol(transport)
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000261
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900262
Roger Meier85fb6de2012-11-02 00:05:42 +0000263class JSONTest(AbstractTest):
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900264 def get_protocol(self, transport):
265 return TJSONProtocol.TJSONProtocolFactory().getProtocol(transport)
Roger Meier85fb6de2012-11-02 00:05:42 +0000266
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900267
Mark Slee5299a952007-10-05 00:13:24 +0000268class AcceleratedBinaryTest(AbstractTest):
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900269 def get_protocol(self, transport):
Nobuaki Sukegawa7af189a2016-02-11 16:21:01 +0900270 return TBinaryProtocol.TBinaryProtocolAcceleratedFactory(fallback=False).getProtocol(transport)
Mark Sleea3302652006-10-25 19:03:32 +0000271
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900272
Nobuaki Sukegawa6525f6a2016-02-11 13:58:39 +0900273class AcceleratedCompactTest(AbstractTest):
274 def get_protocol(self, transport):
Nobuaki Sukegawa7af189a2016-02-11 16:21:01 +0900275 return TCompactProtocol.TCompactProtocolAcceleratedFactory(fallback=False).getProtocol(transport)
Nobuaki Sukegawa6525f6a2016-02-11 13:58:39 +0900276
277
David Reiss9ff3b9d2008-02-15 01:10:23 +0000278def suite():
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900279 suite = unittest.TestSuite()
280 loader = unittest.TestLoader()
281 if options.proto == 'binary': # look for --proto on cmdline
282 suite.addTest(loader.loadTestsFromTestCase(NormalBinaryTest))
283 elif options.proto == 'accel':
284 suite.addTest(loader.loadTestsFromTestCase(AcceleratedBinaryTest))
285 elif options.proto == 'compact':
286 suite.addTest(loader.loadTestsFromTestCase(CompactTest))
Nobuaki Sukegawa6525f6a2016-02-11 13:58:39 +0900287 elif options.proto == 'accelc':
288 suite.addTest(loader.loadTestsFromTestCase(AcceleratedCompactTest))
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900289 elif options.proto == 'json':
290 suite.addTest(loader.loadTestsFromTestCase(JSONTest))
291 else:
292 raise AssertionError('Unknown protocol given with --protocol: %s' % options.proto)
293 return suite
Mark Slee5299a952007-10-05 00:13:24 +0000294
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900295
David Reiss74421272008-11-07 23:09:31 +0000296class OwnArgsTestProgram(unittest.TestProgram):
297 def parseArgs(self, argv):
298 if args:
299 self.testNames = args
300 else:
Nobuaki Sukegawaa185d7e2015-11-06 21:24:24 +0900301 self.testNames = ([self.defaultTest])
David Reiss74421272008-11-07 23:09:31 +0000302 self.createTests()
303
David Reiss9ff3b9d2008-02-15 01:10:23 +0000304if __name__ == "__main__":
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900305 parser = OptionParser()
306 parser.add_option('--libpydir', type='string', dest='libpydir',
307 help='include this directory in sys.path for locating library code')
308 parser.add_option('--genpydir', type='string', dest='genpydir',
309 help='include this directory in sys.path for locating generated code')
310 parser.add_option("--port", type="int", dest="port",
311 help="connect to server at port")
312 parser.add_option("--host", type="string", dest="host",
313 help="connect to server")
314 parser.add_option("--zlib", action="store_true", dest="zlib",
315 help="use zlib wrapper for compressed transport")
316 parser.add_option("--ssl", action="store_true", dest="ssl",
317 help="use SSL for encrypted transport")
318 parser.add_option("--http", dest="http_path",
319 help="Use the HTTP transport with the specified path")
320 parser.add_option('-v', '--verbose', action="store_const",
321 dest="verbose", const=2,
322 help="verbose output")
323 parser.add_option('-q', '--quiet', action="store_const",
324 dest="verbose", const=0,
325 help="minimal output")
326 parser.add_option('--protocol', dest="proto", type="string",
327 help="protocol to use, one of: accel, binary, compact, json")
328 parser.add_option('--transport', dest="trans", type="string",
329 help="transport to use, one of: buffered, framed")
330 parser.set_defaults(framed=False, http_path=None, verbose=1, host='localhost', port=9090, proto='binary')
331 options, args = parser.parse_args()
Nobuaki Sukegawaa185d7e2015-11-06 21:24:24 +0900332
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900333 if options.genpydir:
334 sys.path.insert(0, os.path.join(SCRIPT_DIR, options.genpydir))
Nobuaki Sukegawa7af189a2016-02-11 16:21:01 +0900335 sys.path.insert(0, local_libpath())
Nobuaki Sukegawaa185d7e2015-11-06 21:24:24 +0900336
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900337 from ThriftTest import ThriftTest
338 from ThriftTest.ttypes import Xtruct, Xtruct2, Numberz, Xception, Xception2
339 from thrift.Thrift import TException
340 from thrift.transport import TTransport
341 from thrift.transport import TSocket
342 from thrift.transport import THttpClient
343 from thrift.transport import TZlibTransport
344 from thrift.protocol import TBinaryProtocol
345 from thrift.protocol import TCompactProtocol
346 from thrift.protocol import TJSONProtocol
Nobuaki Sukegawaa185d7e2015-11-06 21:24:24 +0900347
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900348 OwnArgsTestProgram(defaultTest="suite", testRunner=unittest.TextTestRunner(verbosity=1))