THRIFT-3347 Improve cross test servers and clients
Client: TestSuite, C++, Perl, NodeJS, c_glib, Haskell, Python
Patch: Nobuaki Sukegawa <nsukeg@gmail.com>
This closes #621
diff --git a/test/py/TestClient.py b/test/py/TestClient.py
index 592a541..51111a6 100755
--- a/test/py/TestClient.py
+++ b/test/py/TestClient.py
@@ -19,11 +19,11 @@
# under the License.
#
-import sys, glob, os
-sys.path.insert(0, glob.glob(os.path.join(os.path.dirname(__file__),'../../lib/py/build/lib.*'))[0])
-
-import unittest
+import glob
+import os
+import sys
import time
+import unittest
from optparse import OptionParser
parser = OptionParser()
@@ -53,8 +53,10 @@
parser.set_defaults(framed=False, http_path=None, verbose=1, host='localhost', port=9090, proto='binary')
options, args = parser.parse_args()
-script_dir = os.path.dirname(__file__)
+script_dir = os.path.abspath(os.path.dirname(__file__))
+lib_dir = os.path.join(os.path.dirname(os.path.dirname(script_dir)), 'lib', 'py', 'build', 'lib.*')
sys.path.insert(0, os.path.join(script_dir, options.genpydir))
+sys.path.insert(0, glob.glob(lib_dir)[0])
from ThriftTest import ThriftTest, SecondService
from ThriftTest.ttypes import *
@@ -66,6 +68,7 @@
from thrift.protocol import TCompactProtocol
from thrift.protocol import TJSONProtocol
+
class AbstractTest(unittest.TestCase):
def setUp(self):
if options.http_path:
@@ -95,36 +98,49 @@
self.transport.close()
def testVoid(self):
+ print('testVoid')
self.client.testVoid()
def testString(self):
+ print('testString')
self.assertEqual(self.client.testString('Python' * 20), 'Python' * 20)
self.assertEqual(self.client.testString(''), '')
def testBool(self):
+ print('testBool')
self.assertEqual(self.client.testBool(True), True)
self.assertEqual(self.client.testBool(False), False)
def testByte(self):
+ print('testByte')
self.assertEqual(self.client.testByte(63), 63)
self.assertEqual(self.client.testByte(-127), -127)
def testI32(self):
+ print('testI32')
self.assertEqual(self.client.testI32(-1), -1)
self.assertEqual(self.client.testI32(0), 0)
def testI64(self):
+ print('testI64')
self.assertEqual(self.client.testI64(1), 1)
self.assertEqual(self.client.testI64(-34359738368), -34359738368)
def testDouble(self):
+ print('testDouble')
self.assertEqual(self.client.testDouble(-5.235098235), -5.235098235)
self.assertEqual(self.client.testDouble(0), 0)
self.assertEqual(self.client.testDouble(-1), -1)
- # TODO: def testBinary(self) ...
-
+ def testBinary(self):
+ if isinstance(self, JSONTest):
+ self.skipTest('JSON protocol does not handle binary correctly.')
+ print('testBinary')
+ val = bytearray([i for i in range(0, 256)])
+ self.assertEqual(bytearray(self.client.testBinary(bytes(val))), val)
+
def testStruct(self):
+ print('testStruct')
x = Xtruct()
x.string_thing = "Zero"
x.byte_thing = 1
@@ -134,23 +150,26 @@
self.assertEqual(y, x)
def testNest(self):
- inner = Xtruct(string_thing="Zero", byte_thing=1, i32_thing=-3,
- i64_thing=-5)
+ print('testNest')
+ inner = Xtruct(string_thing="Zero", byte_thing=1, i32_thing=-3, i64_thing=-5)
x = Xtruct2(struct_thing=inner, byte_thing=0, i32_thing=0)
y = self.client.testNest(x)
self.assertEqual(y, x)
def testMap(self):
+ print('testMap')
x = {0:1, 1:2, 2:3, 3:4, -1:-2}
y = self.client.testMap(x)
self.assertEqual(y, x)
def testSet(self):
+ print('testSet')
x = set([8, 1, 42])
y = self.client.testSet(x)
self.assertEqual(y, x)
def testList(self):
+ print('testList')
x = [1, 4, 9, -42]
y = self.client.testList(x)
self.assertEqual(y, x)
diff --git a/test/py/TestServer.py b/test/py/TestServer.py
index 89b74da..b5696ca 100755
--- a/test/py/TestServer.py
+++ b/test/py/TestServer.py
@@ -19,10 +19,16 @@
# under the License.
#
from __future__ import division
-import sys, glob, time, os
-sys.path.insert(0, glob.glob(os.path.join(os.path.dirname(__file__),'../../lib/py/build/lib.*'))[0])
+import glob
+import logging
+import os
+import sys
+import time
from optparse import OptionParser
+# Print TServer log to stdout so that the test-runner can redirect it to log files
+logging.basicConfig()
+
parser = OptionParser()
parser.add_option('--genpydir', type='string', dest='genpydir',
default='gen-py',
@@ -46,8 +52,11 @@
parser.set_defaults(port=9090, verbose=1, proto='binary')
options, args = parser.parse_args()
-script_dir = os.path.dirname(__file__) #<-- absolute dir the script is in
+script_dir = os.path.realpath(os.path.dirname(__file__)) # <-- absolute dir the script is in
+lib_dir = os.path.join(os.path.dirname(os.path.dirname(script_dir)), 'lib', 'py', 'build', 'lib.*')
+
sys.path.insert(0, os.path.join(script_dir, options.genpydir))
+sys.path.insert(0, glob.glob(lib_dir)[0])
from ThriftTest import ThriftTest
from ThriftTest.ttypes import *
@@ -60,65 +69,67 @@
from thrift.protocol import TJSONProtocol
from thrift.server import TServer, TNonblockingServer, THttpServer
-PROT_FACTORIES = {'binary': TBinaryProtocol.TBinaryProtocolFactory,
+PROT_FACTORIES = {
+ 'binary': TBinaryProtocol.TBinaryProtocolFactory,
'accel': TBinaryProtocol.TBinaryProtocolAcceleratedFactory,
'compact': TCompactProtocol.TCompactProtocolFactory,
- 'json': TJSONProtocol.TJSONProtocolFactory}
+ 'json': TJSONProtocol.TJSONProtocolFactory,
+}
-class TestHandler:
+class TestHandler(object):
def testVoid(self):
if options.verbose > 1:
- print 'testVoid()'
+ print('testVoid()')
def testString(self, str):
if options.verbose > 1:
- print 'testString(%s)' % str
+ print('testString(%s)' % str)
return str
def testBool(self, boolean):
if options.verbose > 1:
- print 'testBool(%s)' % str(boolean).lower()
+ print('testBool(%s)' % str(boolean).lower())
return boolean
def testByte(self, byte):
if options.verbose > 1:
- print 'testByte(%d)' % byte
+ print('testByte(%d)' % byte)
return byte
def testI16(self, i16):
if options.verbose > 1:
- print 'testI16(%d)' % i16
+ print('testI16(%d)' % i16)
return i16
def testI32(self, i32):
if options.verbose > 1:
- print 'testI32(%d)' % i32
+ print('testI32(%d)' % i32)
return i32
def testI64(self, i64):
if options.verbose > 1:
- print 'testI64(%d)' % i64
+ print('testI64(%d)' % i64)
return i64
def testDouble(self, dub):
if options.verbose > 1:
- print 'testDouble(%f)' % dub
+ print('testDouble(%f)' % dub)
return dub
def testBinary(self, thing):
if options.verbose > 1:
- print 'testBinary()' # TODO: hex output
- return thring
-
+ print('testBinary()') # TODO: hex output
+ return thing
+
def testStruct(self, thing):
if options.verbose > 1:
- print 'testStruct({%s, %d, %d, %d})' % (thing.string_thing, thing.byte_thing, thing.i32_thing, thing.i64_thing)
+ print('testStruct({%s, %d, %d, %d})' % (thing.string_thing, thing.byte_thing, thing.i32_thing, thing.i64_thing))
return thing
def testException(self, arg):
- #if options.verbose > 1:
- print 'testException(%s)' % arg
+ # if options.verbose > 1:
+ print('testException(%s)' % arg)
if arg == 'Xception':
raise Xception(errorCode=1001, message=arg)
elif arg == 'TException':
@@ -126,7 +137,7 @@
def testMultiException(self, arg0, arg1):
if options.verbose > 1:
- print 'testMultiException(%s, %s)' % (arg0, arg1)
+ print('testMultiException(%s, %s)' % (arg0, arg1))
if arg0 == 'Xception':
raise Xception(errorCode=1001, message='This is an Xception')
elif arg0 == 'Xception2':
@@ -137,54 +148,78 @@
def testOneway(self, seconds):
if options.verbose > 1:
- print 'testOneway(%d) => sleeping...' % seconds
- time.sleep(seconds / 3) # be quick
+ print('testOneway(%d) => sleeping...' % seconds)
+ time.sleep(seconds / 3) # be quick
if options.verbose > 1:
- print 'done sleeping'
+ print('done sleeping')
def testNest(self, thing):
if options.verbose > 1:
- print 'testNest(%s)' % thing
+ print('testNest(%s)' % thing)
return thing
def testMap(self, thing):
if options.verbose > 1:
- print 'testMap(%s)' % thing
+ print('testMap(%s)' % thing)
+ return thing
+
+ def testStringMap(self, thing):
+ if options.verbose > 1:
+ print('testStringMap(%s)' % thing)
return thing
def testSet(self, thing):
if options.verbose > 1:
- print 'testSet(%s)' % thing
+ print('testSet(%s)' % thing)
return thing
def testList(self, thing):
if options.verbose > 1:
- print 'testList(%s)' % thing
+ print('testList(%s)' % thing)
return thing
def testEnum(self, thing):
if options.verbose > 1:
- print 'testEnum(%s)' % thing
+ print('testEnum(%s)' % thing)
return thing
def testTypedef(self, thing):
if options.verbose > 1:
- print 'testTypedef(%s)' % thing
+ print('testTypedef(%s)' % thing)
return thing
def testMapMap(self, thing):
if options.verbose > 1:
- print 'testMapMap(%s)' % thing
- return {thing: {thing: thing}}
+ print('testMapMap(%s)' % thing)
+ return {
+ -4: {
+ -4: -4,
+ -3: -3,
+ -2: -2,
+ -1: -1,
+ },
+ 4: {
+ 4: 4,
+ 3: 3,
+ 2: 2,
+ 1: 1,
+ },
+ }
def testInsanity(self, argument):
if options.verbose > 1:
- print 'testInsanity(%s)' % argument
- return {123489: {Numberz.ONE:argument}}
+ print('testInsanity(%s)' % argument)
+ return {
+ 1: {
+ 2: argument,
+ 3: argument,
+ },
+ 2: {6: Insanity()},
+ }
def testMulti(self, arg0, arg1, arg2, arg3, arg4, arg5):
if options.verbose > 1:
- print 'testMulti(%s)' % [arg0, arg1, arg2, arg3, arg4, arg5]
+ print('testMulti(%s)' % [arg0, arg1, arg2, arg3, arg4, arg5])
return Xtruct(string_thing='Hello2',
byte_thing=arg0, i32_thing=arg1, i64_thing=arg2)
@@ -212,8 +247,7 @@
# set up server transport and transport factory
-rel_path = "../keys/server.pem"
-abs_key_path = os.path.join(script_dir, rel_path)
+abs_key_path = os.path.join(os.path.dirname(script_dir), 'keys', 'server.pem')
host = None
if options.ssl:
@@ -243,14 +277,15 @@
from thrift.server import TProcessPoolServer
server = TProcessPoolServer.TProcessPoolServer(processor, transport, tfactory, pfactory)
server.setNumWorkers(5)
+
def set_alarm():
def clean_shutdown(signum, frame):
for worker in server.workers:
if options.verbose > 0:
- print 'Terminating worker: %s' % worker
+ print('Terminating worker: %s' % worker)
worker.terminate()
if options.verbose > 0:
- print 'Requesting server to stop()'
+ print('Requesting server to stop()')
try:
server.stop()
except: