blob: 4689d634d8a92c60d0226ff7a75c6927dea7d15d [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__))
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +090057lib_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
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +090061from ThriftTest import ThriftTest
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 Sukegawa760511f2015-11-06 21:24:16 +0900108 s1 = u'\b\t\n/\\\\\r{}:パイソン"'
109 s2 = u"""Afrikaans, Alemannisch, Aragonés, العربية, مصرى,
Nobuaki Sukegawa64b8f6c2015-10-10 02:12:48 +0900110 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ú, 粵語"""
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900134 if sys.version_info[0] == 2:
135 s1 = s1.encode('utf8')
136 s2 = s2.encode('utf8')
137 self.assertEqual(self.client.testString(s1), s1)
138 self.assertEqual(self.client.testString(s2), s2)
Mark Sleec9676562006-09-05 17:34:52 +0000139
Nobuaki Sukegawaa649e742015-09-21 13:53:25 +0900140 def testBool(self):
Jens Geyerd629ea02015-09-23 21:16:50 +0200141 print('testBool')
Nobuaki Sukegawaa649e742015-09-21 13:53:25 +0900142 self.assertEqual(self.client.testBool(True), True)
143 self.assertEqual(self.client.testBool(False), False)
144
Mark Slee5299a952007-10-05 00:13:24 +0000145 def testByte(self):
Jens Geyerd629ea02015-09-23 21:16:50 +0200146 print('testByte')
Mark Slee5299a952007-10-05 00:13:24 +0000147 self.assertEqual(self.client.testByte(63), 63)
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000148 self.assertEqual(self.client.testByte(-127), -127)
Mark Sleec98d0502006-09-06 02:42:25 +0000149
Mark Slee5299a952007-10-05 00:13:24 +0000150 def testI32(self):
Jens Geyerd629ea02015-09-23 21:16:50 +0200151 print('testI32')
Mark Slee5299a952007-10-05 00:13:24 +0000152 self.assertEqual(self.client.testI32(-1), -1)
153 self.assertEqual(self.client.testI32(0), 0)
Mark Sleec9676562006-09-05 17:34:52 +0000154
Mark Slee5299a952007-10-05 00:13:24 +0000155 def testI64(self):
Jens Geyerd629ea02015-09-23 21:16:50 +0200156 print('testI64')
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000157 self.assertEqual(self.client.testI64(1), 1)
Mark Slee5299a952007-10-05 00:13:24 +0000158 self.assertEqual(self.client.testI64(-34359738368), -34359738368)
Mark Sleec98d0502006-09-06 02:42:25 +0000159
Mark Slee5299a952007-10-05 00:13:24 +0000160 def testDouble(self):
Jens Geyerd629ea02015-09-23 21:16:50 +0200161 print('testDouble')
Mark Slee5299a952007-10-05 00:13:24 +0000162 self.assertEqual(self.client.testDouble(-5.235098235), -5.235098235)
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000163 self.assertEqual(self.client.testDouble(0), 0)
164 self.assertEqual(self.client.testDouble(-1), -1)
Nobuaki Sukegawa228b3282015-10-10 03:11:49 +0900165 self.assertEqual(self.client.testDouble(-0.000341012439638598279), -0.000341012439638598279)
Mark Sleec9676562006-09-05 17:34:52 +0000166
Jens Geyerd629ea02015-09-23 21:16:50 +0200167 def testBinary(self):
168 if isinstance(self, JSONTest):
169 self.skipTest('JSON protocol does not handle binary correctly.')
170 print('testBinary')
171 val = bytearray([i for i in range(0, 256)])
172 self.assertEqual(bytearray(self.client.testBinary(bytes(val))), val)
173
Mark Slee5299a952007-10-05 00:13:24 +0000174 def testStruct(self):
Jens Geyerd629ea02015-09-23 21:16:50 +0200175 print('testStruct')
Mark Slee5299a952007-10-05 00:13:24 +0000176 x = Xtruct()
177 x.string_thing = "Zero"
178 x.byte_thing = 1
179 x.i32_thing = -3
180 x.i64_thing = -5
181 y = self.client.testStruct(x)
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000182 self.assertEqual(y, x)
Mark Sleefc89d392006-09-04 00:04:39 +0000183
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000184 def testNest(self):
Jens Geyerd629ea02015-09-23 21:16:50 +0200185 print('testNest')
186 inner = Xtruct(string_thing="Zero", byte_thing=1, i32_thing=-3, i64_thing=-5)
Roger Meier85fb6de2012-11-02 00:05:42 +0000187 x = Xtruct2(struct_thing=inner, byte_thing=0, i32_thing=0)
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000188 y = self.client.testNest(x)
189 self.assertEqual(y, x)
190
191 def testMap(self):
Jens Geyerd629ea02015-09-23 21:16:50 +0200192 print('testMap')
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000193 x = {0:1, 1:2, 2:3, 3:4, -1:-2}
194 y = self.client.testMap(x)
195 self.assertEqual(y, x)
196
197 def testSet(self):
Jens Geyerd629ea02015-09-23 21:16:50 +0200198 print('testSet')
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000199 x = set([8, 1, 42])
200 y = self.client.testSet(x)
201 self.assertEqual(y, x)
202
203 def testList(self):
Jens Geyerd629ea02015-09-23 21:16:50 +0200204 print('testList')
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000205 x = [1, 4, 9, -42]
206 y = self.client.testList(x)
207 self.assertEqual(y, x)
208
209 def testEnum(self):
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900210 print('testEnum')
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000211 x = Numberz.FIVE
212 y = self.client.testEnum(x)
213 self.assertEqual(y, x)
214
215 def testTypedef(self):
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900216 print('testTypedef')
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000217 x = 0xffffffffffffff # 7 bytes of 0xff
218 y = self.client.testTypedef(x)
219 self.assertEqual(y, x)
220
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900221 @unittest.skip('Cannot use dict as dict key')
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000222 def testMapMap(self):
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900223 print('testMapMap')
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000224 # 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 +0900225 x = {{1: 10, 2: 20}, {1: 100, 2: 200, 3: 300}, {1: 1000, 2: 2000, 3: 3000, 4: 4000}}
226 y = self.client.testMapMap(x)
227 self.assertEqual(y, x)
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000228
229 def testMulti(self):
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900230 print('testMulti')
Roger Meier85fb6de2012-11-02 00:05:42 +0000231 xpected = Xtruct(string_thing='Hello2', byte_thing=74, i32_thing=0xff00ff, i64_thing=0xffffffffd0d0)
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000232 y = self.client.testMulti(xpected.byte_thing,
233 xpected.i32_thing,
234 xpected.i64_thing,
235 { 0:'abc' },
236 Numberz.FIVE,
Roger Meier76150722014-05-31 22:22:07 +0200237 0xf0f0f0)
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000238 self.assertEqual(y, xpected)
Mark Sleec9676562006-09-05 17:34:52 +0000239
Mark Slee5299a952007-10-05 00:13:24 +0000240 def testException(self):
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900241 print('testException')
Mark Slee5299a952007-10-05 00:13:24 +0000242 self.client.testException('Safe')
243 try:
244 self.client.testException('Xception')
245 self.fail("should have gotten exception")
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900246 except Xception as x:
Mark Slee5299a952007-10-05 00:13:24 +0000247 self.assertEqual(x.errorCode, 1001)
248 self.assertEqual(x.message, 'Xception')
Roger Meier61188a42011-11-01 21:03:33 +0000249 # TODO ensure same behavior for repr within generated python variants
Roger Meierf4eec7a2011-09-11 18:16:21 +0000250 # ensure exception's repr method works
Roger Meier61188a42011-11-01 21:03:33 +0000251 #x_repr = repr(x)
252 #self.assertEqual(x_repr, 'Xception(errorCode=1001, message=\'Xception\')')
Mark Sleec9676562006-09-05 17:34:52 +0000253
David Reissbcaa2ad2008-06-10 22:55:26 +0000254 try:
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900255 self.client.testException('TException')
256 self.fail("should have gotten exception")
257 except TException as x:
David Reissbcaa2ad2008-06-10 22:55:26 +0000258 pass
259
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900260 # Should not throw
261 self.client.testException('success')
262
263 def testMultiException(self):
264 print('testMultiException')
265 try:
266 self.client.testMultiException('Xception', 'ignore')
267 except Xception as ex:
268 self.assertEqual(ex.errorCode, 1001)
269 self.assertEqual(ex.message, 'This is an Xception')
270
271 try:
272 self.client.testMultiException('Xception2', 'ignore')
273 except Xception2 as ex:
274 self.assertEqual(ex.errorCode, 2002)
275 self.assertEqual(ex.struct_thing.string_thing, 'This is an Xception2')
276
277 y = self.client.testMultiException('success', 'foobar')
278 self.assertEqual(y.string_thing, 'foobar')
279
David Reiss6ce401d2009-03-24 20:01:58 +0000280 def testOneway(self):
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900281 print('testOneway')
David Reissdb893b62008-02-18 02:11:48 +0000282 start = time.time()
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000283 self.client.testOneway(1) # type is int, not float
David Reissdb893b62008-02-18 02:11:48 +0000284 end = time.time()
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000285 self.assertTrue(end - start < 3,
David Reiss6ce401d2009-03-24 20:01:58 +0000286 "oneway sleep took %f sec" % (end - start))
Roger Meier76150722014-05-31 22:22:07 +0200287
Todd Lipconf5dea4c2009-12-03 01:18:44 +0000288 def testOnewayThenNormal(self):
Nobuaki Sukegawa01ede042015-09-29 02:16:53 +0900289 print('testOnewayThenNormal')
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000290 self.client.testOneway(1) # type is int, not float
Todd Lipconf5dea4c2009-12-03 01:18:44 +0000291 self.assertEqual(self.client.testString('Python'), 'Python')
David Reissdb893b62008-02-18 02:11:48 +0000292
Roger Meier879cab22014-05-03 17:51:21 +0200293
Mark Slee5299a952007-10-05 00:13:24 +0000294class NormalBinaryTest(AbstractTest):
295 protocol_factory = TBinaryProtocol.TBinaryProtocolFactory()
Mark Sleefc89d392006-09-04 00:04:39 +0000296
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900297
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000298class CompactTest(AbstractTest):
299 protocol_factory = TCompactProtocol.TCompactProtocolFactory()
300
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900301
Roger Meier85fb6de2012-11-02 00:05:42 +0000302class JSONTest(AbstractTest):
303 protocol_factory = TJSONProtocol.TJSONProtocolFactory()
304
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900305
Mark Slee5299a952007-10-05 00:13:24 +0000306class AcceleratedBinaryTest(AbstractTest):
307 protocol_factory = TBinaryProtocol.TBinaryProtocolAcceleratedFactory()
Mark Sleea3302652006-10-25 19:03:32 +0000308
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900309
David Reiss9ff3b9d2008-02-15 01:10:23 +0000310def suite():
311 suite = unittest.TestSuite()
312 loader = unittest.TestLoader()
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900313 if options.proto == 'binary': # look for --proto on cmdline
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000314 suite.addTest(loader.loadTestsFromTestCase(NormalBinaryTest))
315 elif options.proto == 'accel':
316 suite.addTest(loader.loadTestsFromTestCase(AcceleratedBinaryTest))
317 elif options.proto == 'compact':
318 suite.addTest(loader.loadTestsFromTestCase(CompactTest))
Roger Meier85fb6de2012-11-02 00:05:42 +0000319 elif options.proto == 'json':
320 suite.addTest(loader.loadTestsFromTestCase(JSONTest))
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000321 else:
Roger Meier76150722014-05-31 22:22:07 +0200322 raise AssertionError('Unknown protocol given with --protocol: %s' % options.proto)
David Reiss9ff3b9d2008-02-15 01:10:23 +0000323 return suite
Mark Slee5299a952007-10-05 00:13:24 +0000324
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900325
David Reiss74421272008-11-07 23:09:31 +0000326class OwnArgsTestProgram(unittest.TestProgram):
327 def parseArgs(self, argv):
328 if args:
329 self.testNames = args
330 else:
331 self.testNames = (self.defaultTest,)
332 self.createTests()
333
David Reiss9ff3b9d2008-02-15 01:10:23 +0000334if __name__ == "__main__":
Roger Meierf4eec7a2011-09-11 18:16:21 +0000335 OwnArgsTestProgram(defaultTest="suite", testRunner=unittest.TextTestRunner(verbosity=1))