blob: edab610b1592d29849035bb4d791dd306dbfe9a6 [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):
James E. King III6f8c99e2018-03-24 16:32:02 -040035 if options.trans == 'http':
36 uri = '{0}://{1}:{2}{3}'.format(('https' if options.ssl else 'http'),
37 options.host,
38 options.port,
39 (options.http_path if options.http_path else '/'))
40 if options.ssl:
41 __cafile = os.path.join(os.path.dirname(SCRIPT_DIR), "keys", "CA.pem")
42 __certfile = os.path.join(os.path.dirname(SCRIPT_DIR), "keys", "client.crt")
43 __keyfile = os.path.join(os.path.dirname(SCRIPT_DIR), "keys", "client.key")
44 self.transport = THttpClient.THttpClient(uri, cafile=__cafile, cert_file=__certfile, key_file=__keyfile)
45 else:
46 self.transport = THttpClient.THttpClient(uri)
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090047 else:
48 if options.ssl:
49 from thrift.transport import TSSLSocket
50 socket = TSSLSocket.TSSLSocket(options.host, options.port, validate=False)
51 else:
52 socket = TSocket.TSocket(options.host, options.port)
53 # frame or buffer depending upon args
54 self.transport = TTransport.TBufferedTransport(socket)
55 if options.trans == 'framed':
56 self.transport = TTransport.TFramedTransport(socket)
57 elif options.trans == 'buffered':
58 self.transport = TTransport.TBufferedTransport(socket)
59 elif options.trans == '':
60 raise AssertionError('Unknown --transport option: %s' % options.trans)
61 if options.zlib:
62 self.transport = TZlibTransport.TZlibTransport(self.transport, 9)
63 self.transport.open()
64 protocol = self.get_protocol(self.transport)
65 self.client = ThriftTest.Client(protocol)
David Reiss0c90f6f2008-02-06 22:18:40 +000066
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090067 def tearDown(self):
68 self.transport.close()
Mark Sleefc89d392006-09-04 00:04:39 +000069
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090070 def testVoid(self):
71 print('testVoid')
72 self.client.testVoid()
David Reiss0c90f6f2008-02-06 22:18:40 +000073
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090074 def testString(self):
75 print('testString')
76 self.assertEqual(self.client.testString('Python' * 20), 'Python' * 20)
77 self.assertEqual(self.client.testString(''), '')
78 s1 = u'\b\t\n/\\\\\r{}:パイソン"'
79 s2 = u"""Afrikaans, Alemannisch, Aragonés, العربية, مصرى,
Nobuaki Sukegawa64b8f6c2015-10-10 02:12:48 +090080 Asturianu, Aymar aru, Azərbaycan, Башҡорт, Boarisch, Žemaitėška,
81 Беларуская, Беларуская (тарашкевіца), Български, Bamanankan,
82 বাংলা, Brezhoneg, Bosanski, Català, Mìng-dĕ̤ng-ngṳ̄, Нохчийн,
83 Cebuano, ᏣᎳᎩ, Česky, Словѣ́ньскъ / ⰔⰎⰑⰂⰡⰐⰠⰔⰍⰟ, Чӑвашла, Cymraeg,
84 Dansk, Zazaki, ދިވެހިބަސް, Ελληνικά, Emiliàn e rumagnòl, English,
85 Esperanto, Español, Eesti, Euskara, فارسی, Suomi, Võro, Føroyskt,
86 Français, Arpetan, Furlan, Frysk, Gaeilge, 贛語, Gàidhlig, Galego,
87 Avañe'ẽ, ગુજરાતી, Gaelg, עברית, हिन्दी, Fiji Hindi, Hrvatski,
88 Kreyòl ayisyen, Magyar, Հայերեն, Interlingua, Bahasa Indonesia,
89 Ilokano, Ido, Íslenska, Italiano, 日本語, Lojban, Basa Jawa,
90 ქართული, Kongo, Kalaallisut, ಕನ್ನಡ, 한국어, Къарачай-Малкъар,
91 Ripoarisch, Kurdî, Коми, Kernewek, Кыргызча, Latina, Ladino,
92 Lëtzebuergesch, Limburgs, Lingála, ລາວ, Lietuvių, Latviešu, Basa
93 Banyumasan, Malagasy, Македонски, മലയാളം, मराठी, مازِرونی, Bahasa
94 Melayu, Nnapulitano, Nedersaksisch, नेपाल भाषा, Nederlands, ‪
95 Norsk (nynorsk)‬, ‪Norsk (bokmål)‬, Nouormand, Diné bizaad,
96 Occitan, Иронау, Papiamentu, Deitsch, Polski, پنجابی, پښتو,
97 Norfuk / Pitkern, Português, Runa Simi, Rumantsch, Romani, Română,
98 Русский, Саха тыла, Sardu, Sicilianu, Scots, Sámegiella, Simple
99 English, Slovenčina, Slovenščina, Српски / Srpski, Seeltersk,
100 Svenska, Kiswahili, தமிழ், తెలుగు, Тоҷикӣ, ไทย, Türkmençe, Tagalog,
101 Türkçe, Татарча/Tatarça, Українська, اردو, Tiếng Việt, Volapük,
102 Walon, Winaray, 吴语, isiXhosa, ייִדיש, Yorùbá, Zeêuws, 中文,
103 Bân-lâm-gú, 粵語"""
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900104 if sys.version_info[0] == 2 and os.environ.get('THRIFT_TEST_PY_NO_UTF8STRINGS'):
105 s1 = s1.encode('utf8')
106 s2 = s2.encode('utf8')
107 self.assertEqual(self.client.testString(s1), s1)
108 self.assertEqual(self.client.testString(s2), s2)
Mark Sleec9676562006-09-05 17:34:52 +0000109
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900110 def testBool(self):
111 print('testBool')
112 self.assertEqual(self.client.testBool(True), True)
113 self.assertEqual(self.client.testBool(False), False)
Nobuaki Sukegawaa649e742015-09-21 13:53:25 +0900114
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900115 def testByte(self):
116 print('testByte')
117 self.assertEqual(self.client.testByte(63), 63)
118 self.assertEqual(self.client.testByte(-127), -127)
Mark Sleec98d0502006-09-06 02:42:25 +0000119
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900120 def testI32(self):
121 print('testI32')
122 self.assertEqual(self.client.testI32(-1), -1)
123 self.assertEqual(self.client.testI32(0), 0)
Mark Sleec9676562006-09-05 17:34:52 +0000124
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900125 def testI64(self):
126 print('testI64')
127 self.assertEqual(self.client.testI64(1), 1)
128 self.assertEqual(self.client.testI64(-34359738368), -34359738368)
Mark Sleec98d0502006-09-06 02:42:25 +0000129
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900130 def testDouble(self):
131 print('testDouble')
132 self.assertEqual(self.client.testDouble(-5.235098235), -5.235098235)
133 self.assertEqual(self.client.testDouble(0), 0)
134 self.assertEqual(self.client.testDouble(-1), -1)
135 self.assertEqual(self.client.testDouble(-0.000341012439638598279), -0.000341012439638598279)
Mark Sleec9676562006-09-05 17:34:52 +0000136
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900137 def testBinary(self):
138 print('testBinary')
139 val = bytearray([i for i in range(0, 256)])
140 self.assertEqual(bytearray(self.client.testBinary(bytes(val))), val)
Jens Geyerd629ea02015-09-23 21:16:50 +0200141
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900142 def testStruct(self):
143 print('testStruct')
144 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)
150 self.assertEqual(y, x)
Mark Sleefc89d392006-09-04 00:04:39 +0000151
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900152 def testNest(self):
153 print('testNest')
154 inner = Xtruct(string_thing="Zero", byte_thing=1, i32_thing=-3, i64_thing=-5)
155 x = Xtruct2(struct_thing=inner, byte_thing=0, i32_thing=0)
156 y = self.client.testNest(x)
157 self.assertEqual(y, x)
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000158
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900159 def testMap(self):
160 print('testMap')
161 x = {0: 1, 1: 2, 2: 3, 3: 4, -1: -2}
162 y = self.client.testMap(x)
163 self.assertEqual(y, x)
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000164
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900165 def testSet(self):
166 print('testSet')
167 x = set([8, 1, 42])
168 y = self.client.testSet(x)
169 self.assertEqual(y, x)
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000170
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900171 def testList(self):
172 print('testList')
173 x = [1, 4, 9, -42]
174 y = self.client.testList(x)
175 self.assertEqual(y, x)
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000176
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900177 def testEnum(self):
178 print('testEnum')
179 x = Numberz.FIVE
180 y = self.client.testEnum(x)
181 self.assertEqual(y, x)
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000182
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900183 def testTypedef(self):
184 print('testTypedef')
185 x = 0xffffffffffffff # 7 bytes of 0xff
186 y = self.client.testTypedef(x)
187 self.assertEqual(y, x)
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000188
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900189 def testMapMap(self):
190 print('testMapMap')
191 x = {
192 -4: {-4: -4, -3: -3, -2: -2, -1: -1},
193 4: {4: 4, 3: 3, 2: 2, 1: 1},
194 }
195 y = self.client.testMapMap(42)
196 self.assertEqual(y, x)
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000197
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900198 def testMulti(self):
199 print('testMulti')
200 xpected = Xtruct(string_thing='Hello2', byte_thing=74, i32_thing=0xff00ff, i64_thing=0xffffffffd0d0)
201 y = self.client.testMulti(xpected.byte_thing,
202 xpected.i32_thing,
203 xpected.i64_thing,
204 {0: 'abc'},
205 Numberz.FIVE,
206 0xf0f0f0)
207 self.assertEqual(y, xpected)
Mark Sleec9676562006-09-05 17:34:52 +0000208
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900209 def testException(self):
210 print('testException')
211 self.client.testException('Safe')
212 try:
213 self.client.testException('Xception')
214 self.fail("should have gotten exception")
215 except Xception as x:
216 self.assertEqual(x.errorCode, 1001)
217 self.assertEqual(x.message, 'Xception')
218 # TODO ensure same behavior for repr within generated python variants
219 # ensure exception's repr method works
220 # x_repr = repr(x)
221 # self.assertEqual(x_repr, 'Xception(errorCode=1001, message=\'Xception\')')
Mark Sleec9676562006-09-05 17:34:52 +0000222
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900223 try:
224 self.client.testException('TException')
225 self.fail("should have gotten exception")
226 except TException as x:
227 pass
David Reissbcaa2ad2008-06-10 22:55:26 +0000228
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900229 # Should not throw
230 self.client.testException('success')
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900231
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900232 def testMultiException(self):
233 print('testMultiException')
234 try:
235 self.client.testMultiException('Xception', 'ignore')
236 except Xception as ex:
237 self.assertEqual(ex.errorCode, 1001)
238 self.assertEqual(ex.message, 'This is an Xception')
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900239
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900240 try:
241 self.client.testMultiException('Xception2', 'ignore')
242 except Xception2 as ex:
243 self.assertEqual(ex.errorCode, 2002)
244 self.assertEqual(ex.struct_thing.string_thing, 'This is an Xception2')
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900245
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900246 y = self.client.testMultiException('success', 'foobar')
247 self.assertEqual(y.string_thing, 'foobar')
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900248
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900249 def testOneway(self):
250 print('testOneway')
251 start = time.time()
252 self.client.testOneway(1) # type is int, not float
253 end = time.time()
254 self.assertTrue(end - start < 3,
255 "oneway sleep took %f sec" % (end - start))
Roger Meier76150722014-05-31 22:22:07 +0200256
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900257 def testOnewayThenNormal(self):
258 print('testOnewayThenNormal')
259 self.client.testOneway(1) # type is int, not float
260 self.assertEqual(self.client.testString('Python'), 'Python')
David Reissdb893b62008-02-18 02:11:48 +0000261
Roger Meier879cab22014-05-03 17:51:21 +0200262
Mark Slee5299a952007-10-05 00:13:24 +0000263class NormalBinaryTest(AbstractTest):
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900264 def get_protocol(self, transport):
265 return TBinaryProtocol.TBinaryProtocolFactory().getProtocol(transport)
Mark Sleefc89d392006-09-04 00:04:39 +0000266
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900267
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000268class CompactTest(AbstractTest):
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900269 def get_protocol(self, transport):
270 return TCompactProtocol.TCompactProtocolFactory().getProtocol(transport)
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000271
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900272
Roger Meier85fb6de2012-11-02 00:05:42 +0000273class JSONTest(AbstractTest):
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900274 def get_protocol(self, transport):
275 return TJSONProtocol.TJSONProtocolFactory().getProtocol(transport)
Roger Meier85fb6de2012-11-02 00:05:42 +0000276
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900277
Mark Slee5299a952007-10-05 00:13:24 +0000278class AcceleratedBinaryTest(AbstractTest):
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900279 def get_protocol(self, transport):
Nobuaki Sukegawa7af189a2016-02-11 16:21:01 +0900280 return TBinaryProtocol.TBinaryProtocolAcceleratedFactory(fallback=False).getProtocol(transport)
Mark Sleea3302652006-10-25 19:03:32 +0000281
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900282
Nobuaki Sukegawa6525f6a2016-02-11 13:58:39 +0900283class AcceleratedCompactTest(AbstractTest):
284 def get_protocol(self, transport):
Nobuaki Sukegawa7af189a2016-02-11 16:21:01 +0900285 return TCompactProtocol.TCompactProtocolAcceleratedFactory(fallback=False).getProtocol(transport)
Nobuaki Sukegawa6525f6a2016-02-11 13:58:39 +0900286
287
David Reiss9ff3b9d2008-02-15 01:10:23 +0000288def suite():
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900289 suite = unittest.TestSuite()
290 loader = unittest.TestLoader()
291 if options.proto == 'binary': # look for --proto on cmdline
292 suite.addTest(loader.loadTestsFromTestCase(NormalBinaryTest))
293 elif options.proto == 'accel':
294 suite.addTest(loader.loadTestsFromTestCase(AcceleratedBinaryTest))
295 elif options.proto == 'compact':
296 suite.addTest(loader.loadTestsFromTestCase(CompactTest))
Nobuaki Sukegawa6525f6a2016-02-11 13:58:39 +0900297 elif options.proto == 'accelc':
298 suite.addTest(loader.loadTestsFromTestCase(AcceleratedCompactTest))
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900299 elif options.proto == 'json':
300 suite.addTest(loader.loadTestsFromTestCase(JSONTest))
301 else:
302 raise AssertionError('Unknown protocol given with --protocol: %s' % options.proto)
303 return suite
Mark Slee5299a952007-10-05 00:13:24 +0000304
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900305
David Reiss74421272008-11-07 23:09:31 +0000306class OwnArgsTestProgram(unittest.TestProgram):
307 def parseArgs(self, argv):
308 if args:
309 self.testNames = args
310 else:
Nobuaki Sukegawaa185d7e2015-11-06 21:24:24 +0900311 self.testNames = ([self.defaultTest])
David Reiss74421272008-11-07 23:09:31 +0000312 self.createTests()
313
James E. King, III0ad20bd2017-09-30 15:44:16 -0700314
David Reiss9ff3b9d2008-02-15 01:10:23 +0000315if __name__ == "__main__":
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900316 parser = OptionParser()
317 parser.add_option('--libpydir', type='string', dest='libpydir',
318 help='include this directory in sys.path for locating library code')
319 parser.add_option('--genpydir', type='string', dest='genpydir',
320 help='include this directory in sys.path for locating generated code')
321 parser.add_option("--port", type="int", dest="port",
322 help="connect to server at port")
323 parser.add_option("--host", type="string", dest="host",
324 help="connect to server")
325 parser.add_option("--zlib", action="store_true", dest="zlib",
326 help="use zlib wrapper for compressed transport")
327 parser.add_option("--ssl", action="store_true", dest="ssl",
328 help="use SSL for encrypted transport")
329 parser.add_option("--http", dest="http_path",
330 help="Use the HTTP transport with the specified path")
331 parser.add_option('-v', '--verbose', action="store_const",
332 dest="verbose", const=2,
333 help="verbose output")
334 parser.add_option('-q', '--quiet', action="store_const",
335 dest="verbose", const=0,
336 help="minimal output")
337 parser.add_option('--protocol', dest="proto", type="string",
James E. King III6f8c99e2018-03-24 16:32:02 -0400338 help="protocol to use, one of: accel, accelc, binary, compact, json")
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900339 parser.add_option('--transport', dest="trans", type="string",
James E. King III6f8c99e2018-03-24 16:32:02 -0400340 help="transport to use, one of: buffered, framed, http")
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900341 parser.set_defaults(framed=False, http_path=None, verbose=1, host='localhost', port=9090, proto='binary')
342 options, args = parser.parse_args()
Nobuaki Sukegawaa185d7e2015-11-06 21:24:24 +0900343
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900344 if options.genpydir:
345 sys.path.insert(0, os.path.join(SCRIPT_DIR, options.genpydir))
Nobuaki Sukegawa7af189a2016-02-11 16:21:01 +0900346 sys.path.insert(0, local_libpath())
Nobuaki Sukegawaa185d7e2015-11-06 21:24:24 +0900347
James E. King III6f8c99e2018-03-24 16:32:02 -0400348 if options.http_path:
349 options.trans = 'http'
350
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900351 from ThriftTest import ThriftTest
352 from ThriftTest.ttypes import Xtruct, Xtruct2, Numberz, Xception, Xception2
353 from thrift.Thrift import TException
354 from thrift.transport import TTransport
355 from thrift.transport import TSocket
356 from thrift.transport import THttpClient
357 from thrift.transport import TZlibTransport
358 from thrift.protocol import TBinaryProtocol
359 from thrift.protocol import TCompactProtocol
360 from thrift.protocol import TJSONProtocol
Nobuaki Sukegawaa185d7e2015-11-06 21:24:24 +0900361
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900362 OwnArgsTestProgram(defaultTest="suite", testRunner=unittest.TextTestRunner(verbosity=1))