THRIFT-1857 Python 3 Support Client: Python Patch: Nobuaki Sukegawa Add py3 cross test
Project: http://git-wip-us.apache.org/repos/asf/thrift/repo Commit: http://git-wip-us.apache.org/repos/asf/thrift/commit/a185d7e7 Tree: http://git-wip-us.apache.org/repos/asf/thrift/tree/a185d7e7 Diff: http://git-wip-us.apache.org/repos/asf/thrift/diff/a185d7e7 Branch: refs/heads/master Commit: a185d7e78589a42e076379ae7165857e5e828e5c Parents: 760511f Author: Nobuaki Sukegawa <[email protected]> Authored: Fri Nov 6 21:24:24 2015 +0900 Committer: Nobuaki Sukegawa <[email protected]> Committed: Fri Nov 6 21:24:24 2015 +0900 ---------------------------------------------------------------------- Makefile.am | 2 +- build/docker/centos/Dockerfile | 2 +- build/docker/ubuntu/Dockerfile | 2 +- build/travis/installDependencies.sh | 2 +- configure.ac | 12 ++ contrib/Vagrantfile | 2 +- lib/py/Makefile.am | 11 +- test/known_failures_Linux.json | 14 ++ test/py/TestClient.py | 129 ++++++++-------- test/py/TestServer.py | 251 ++++++++++++++++--------------- test/tests.json | 39 +++++ 11 files changed, 280 insertions(+), 186 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/thrift/blob/a185d7e7/Makefile.am ---------------------------------------------------------------------- diff --git a/Makefile.am b/Makefile.am index 73bc48f..812a40a 100755 --- a/Makefile.am +++ b/Makefile.am @@ -49,7 +49,7 @@ empty := space := $(empty) $(empty) comma := , -CROSS_LANGS = @MAYBE_CPP@ @MAYBE_C_GLIB@ @MAYBE_JAVA@ @MAYBE_CSHARP@ @MAYBE_PYTHON@ @MAYBE_RUBY@ @MAYBE_HASKELL@ @MAYBE_PERL@ @MAYBE_PHP@ @MAYBE_GO@ @MAYBE_NODEJS@ @MAYBE_DART@ @MAYBE_ERLANG@ +CROSS_LANGS = @MAYBE_CPP@ @MAYBE_C_GLIB@ @MAYBE_JAVA@ @MAYBE_CSHARP@ @MAYBE_PYTHON@ @MAYBE_PY3@ @MAYBE_RUBY@ @MAYBE_HASKELL@ @MAYBE_PERL@ @MAYBE_PHP@ @MAYBE_GO@ @MAYBE_NODEJS@ @MAYBE_DART@ @MAYBE_ERLANG@ CROSS_LANGS_COMMA_SEPARATED = $(subst $(space),$(comma),$(CROSS_LANGS)) cross: precross http://git-wip-us.apache.org/repos/asf/thrift/blob/a185d7e7/build/docker/centos/Dockerfile ---------------------------------------------------------------------- diff --git a/build/docker/centos/Dockerfile b/build/docker/centos/Dockerfile index 8d5596a..2ba73c3 100644 --- a/build/docker/centos/Dockerfile +++ b/build/docker/centos/Dockerfile @@ -50,7 +50,7 @@ RUN yum install -y libboost-dev libevent-devel RUN yum install -y ant junit ant-nodeps ant-junit java-1.7.0-openjdk-devel # Python Dependencies -RUN yum install -y python-devel python-setuptools python-twisted +RUN yum install -y python-devel python-setuptools python-twisted python-six # Ruby Dependencies RUN yum install -y ruby ruby-devel rubygems && \ http://git-wip-us.apache.org/repos/asf/thrift/blob/a185d7e7/build/docker/ubuntu/Dockerfile ---------------------------------------------------------------------- diff --git a/build/docker/ubuntu/Dockerfile b/build/docker/ubuntu/Dockerfile index 0b02a70..d8bac0c 100644 --- a/build/docker/ubuntu/Dockerfile +++ b/build/docker/ubuntu/Dockerfile @@ -37,7 +37,7 @@ RUN apt-get install -y ant openjdk-7-jdk maven && \ # Python dependencies RUN apt-get install -y python-all python-all-dev python-all-dbg python-setuptools python-support \ - python-twisted python-zope.interface python-six + python-twisted python-zope.interface python-six python3-six # Ruby dependencies RUN apt-get install -y ruby ruby-dev && \ http://git-wip-us.apache.org/repos/asf/thrift/blob/a185d7e7/build/travis/installDependencies.sh ---------------------------------------------------------------------- diff --git a/build/travis/installDependencies.sh b/build/travis/installDependencies.sh index df12640..4945fd4 100755 --- a/build/travis/installDependencies.sh +++ b/build/travis/installDependencies.sh @@ -27,7 +27,7 @@ sudo apt-get install -qq ant openjdk-7-jdk sudo update-java-alternatives -s java-1.7.0-openjdk-amd64 # Python dependencies -sudo apt-get install -qq python-all python-all-dev python-all-dbg python-setuptools python-support python-twisted python-six +sudo apt-get install -qq python-all python-all-dev python-all-dbg python-setuptools python-support python-twisted python-six python3-six # Ruby dependencies sudo apt-get install -qq ruby ruby-dev http://git-wip-us.apache.org/repos/asf/thrift/blob/a185d7e7/configure.ac ---------------------------------------------------------------------- diff --git a/configure.ac b/configure.ac index 3d1b15f..777300a 100755 --- a/configure.ac +++ b/configure.ac @@ -285,6 +285,16 @@ if test "$with_python" = "yes"; then fi AM_CONDITIONAL(WITH_PYTHON, [test "$have_python" = "yes"]) +# Find "python3" executable. +# It's distro specific and far from ideal but needed to cross test py2-3 at once. +if test "x$have_python" = "xyes"; then + AC_PATH_PROG([PYTHON3], [python3]) + if test "x$PYTHON3" != "x" && test "x$PYTHON3" != "x:" ; then + have_py3="yes" + fi +fi +AM_CONDITIONAL(WITH_PY3, [test "$have_py3" = "yes"]) + AX_THRIFT_LIB(perl, [Perl], yes) if test "$with_perl" = "yes"; then AC_PATH_PROG([PERL], [perl]) @@ -782,6 +792,8 @@ if test "$have_csharp" = "yes" ; then MAYBE_CSHARP="csharp" ; else MAYBE_CSHARP= AC_SUBST([MAYBE_CSHARP]) if test "$have_python" = "yes" ; then MAYBE_PYTHON="py" ; else MAYBE_PYTHON="" ; fi AC_SUBST([MAYBE_PYTHON]) +if test "$have_py3" = "yes" ; then MAYBE_PY3="py3" ; else MAYBE_PY3="" ; fi +AC_SUBST([MAYBE_PY3]) if test "$have_ruby" = "yes" ; then MAYBE_RUBY="rb" ; else MAYBE_RUBY="" ; fi AC_SUBST([MAYBE_RUBY]) if test "$have_haskell" = "yes" ; then MAYBE_HASKELL="hs" ; else MAYBE_HASKELL="" ; fi http://git-wip-us.apache.org/repos/asf/thrift/blob/a185d7e7/contrib/Vagrantfile ---------------------------------------------------------------------- diff --git a/contrib/Vagrantfile b/contrib/Vagrantfile index 2091110..3bcc46a 100644 --- a/contrib/Vagrantfile +++ b/contrib/Vagrantfile @@ -46,7 +46,7 @@ sudo apt-get install -qq libboost-dev libboost-test-dev libboost-program-options sudo apt-get install -qq ant openjdk-7-jdk maven # Python dependencies -sudo apt-get install -qq python-all python-all-dev python-all-dbg python-setuptools python-support python-six +sudo apt-get install -qq python-all python-all-dev python-all-dbg python-setuptools python-support python-six python3-six # Ruby dependencies sudo apt-get install -qq ruby ruby-dev http://git-wip-us.apache.org/repos/asf/thrift/blob/a185d7e7/lib/py/Makefile.am ---------------------------------------------------------------------- diff --git a/lib/py/Makefile.am b/lib/py/Makefile.am index 2cdbb24..b88b6be 100755 --- a/lib/py/Makefile.am +++ b/lib/py/Makefile.am @@ -19,7 +19,16 @@ AUTOMAKE_OPTIONS = serial-tests DESTDIR ?= / -all-local: +if WITH_PY3 +py3-build: + $(PYTHON3) setup.py build +else +py3-build: +endif + +testing: + +all-local: py3-build testing $(PYTHON) setup.py build # We're ignoring prefix here because site-packages seems to be http://git-wip-us.apache.org/repos/asf/thrift/blob/a185d7e7/test/known_failures_Linux.json ---------------------------------------------------------------------- diff --git a/test/known_failures_Linux.json b/test/known_failures_Linux.json index 4c78c52..3625fa9 100644 --- a/test/known_failures_Linux.json +++ b/test/known_failures_Linux.json @@ -88,6 +88,8 @@ "hs-java_json_framed-ip", "hs-nodejs_json_buffered-ip", "hs-nodejs_json_framed-ip", + "hs-py3_json_buffered-ip", + "hs-py3_json_framed-ip", "hs-py_json_buffered-ip", "hs-py_json_framed-ip", "hs-rb_json_buffered-ip", @@ -120,6 +122,14 @@ "nodejs-java_compact_framed-ip", "nodejs-java_compact_framed-ip-ssl", "nodejs-java_json_buffered-ip-ssl", + "nodejs-py3_compact_buffered-ip", + "nodejs-py3_compact_buffered-ip-ssl", + "nodejs-py3_compact_framed-ip", + "nodejs-py3_compact_framed-ip-ssl", + "nodejs-py3_json_buffered-ip", + "nodejs-py3_json_buffered-ip-ssl", + "nodejs-py3_json_framed-ip", + "nodejs-py3_json_framed-ip-ssl", "nodejs-py_compact_buffered-ip", "nodejs-py_compact_buffered-ip-ssl", "nodejs-py_compact_framed-ip", @@ -139,6 +149,10 @@ "py-nodejs_json_buffered-ip-ssl", "py-nodejs_json_framed-ip", "py-nodejs_json_framed-ip-ssl", + "py3-hs_json_buffered-ip", + "py3-hs_json_framed-ip", + "py3-perl_binary_buffered-ip-ssl", + "py3-perl_binary_framed-ip-ssl", "rb-hs_json_buffered-ip", "rb-hs_json_framed-ip", "rb-nodejs_json_buffered-ip", http://git-wip-us.apache.org/repos/asf/thrift/blob/a185d7e7/test/py/TestClient.py ---------------------------------------------------------------------- diff --git a/test/py/TestClient.py b/test/py/TestClient.py index 4689d63..5b858ef 100755 --- a/test/py/TestClient.py +++ b/test/py/TestClient.py @@ -26,47 +26,9 @@ import time import unittest from optparse import OptionParser -parser = OptionParser() -parser.add_option('--genpydir', type='string', dest='genpydir', - default='gen-py', - help='include this local directory in sys.path for locating generated code') -parser.add_option("--port", type="int", dest="port", - help="connect to server at port") -parser.add_option("--host", type="string", dest="host", - help="connect to server") -parser.add_option("--zlib", action="store_true", dest="zlib", - help="use zlib wrapper for compressed transport") -parser.add_option("--ssl", action="store_true", dest="ssl", - help="use SSL for encrypted transport") -parser.add_option("--http", dest="http_path", - help="Use the HTTP transport with the specified path") -parser.add_option('-v', '--verbose', action="store_const", - dest="verbose", const=2, - help="verbose output") -parser.add_option('-q', '--quiet', action="store_const", - dest="verbose", const=0, - help="minimal output") -parser.add_option('--protocol', dest="proto", type="string", - help="protocol to use, one of: accel, binary, compact, json") -parser.add_option('--transport', dest="trans", type="string", - help="transport to use, one of: buffered, framed") -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.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 -from ThriftTest.ttypes import * -from thrift.transport import TTransport -from thrift.transport import TSocket -from thrift.transport import THttpClient -from thrift.transport import TZlibTransport -from thrift.protocol import TBinaryProtocol -from thrift.protocol import TCompactProtocol -from thrift.protocol import TJSONProtocol +SCRIPT_DIR = os.path.abspath(os.path.dirname(__file__)) +ROOT_DIR = os.path.dirname(os.path.dirname(SCRIPT_DIR)) +DEFAULT_LIBDIR_GLOB = os.path.join(ROOT_DIR, 'lib', 'py', 'build', 'lib.*') class AbstractTest(unittest.TestCase): @@ -90,11 +52,10 @@ class AbstractTest(unittest.TestCase): if options.zlib: self.transport = TZlibTransport.TZlibTransport(self.transport, 9) self.transport.open() - protocol = self.protocol_factory.getProtocol(self.transport) + protocol = self.get_protocol(self.transport) self.client = ThriftTest.Client(protocol) def tearDown(self): - # Close! self.transport.close() def testVoid(self): @@ -190,7 +151,7 @@ class AbstractTest(unittest.TestCase): def testMap(self): print('testMap') - x = {0:1, 1:2, 2:3, 3:4, -1:-2} + x = {0: 1, 1: 2, 2: 3, 3: 4, -1: -2} y = self.client.testMap(x) self.assertEqual(y, x) @@ -214,7 +175,7 @@ class AbstractTest(unittest.TestCase): def testTypedef(self): print('testTypedef') - x = 0xffffffffffffff # 7 bytes of 0xff + x = 0xffffffffffffff # 7 bytes of 0xff y = self.client.testTypedef(x) self.assertEqual(y, x) @@ -230,11 +191,11 @@ class AbstractTest(unittest.TestCase): print('testMulti') xpected = Xtruct(string_thing='Hello2', byte_thing=74, i32_thing=0xff00ff, i64_thing=0xffffffffd0d0) y = self.client.testMulti(xpected.byte_thing, - xpected.i32_thing, - xpected.i64_thing, - { 0:'abc' }, - Numberz.FIVE, - 0xf0f0f0) + xpected.i32_thing, + xpected.i64_thing, + {0: 'abc'}, + Numberz.FIVE, + 0xf0f0f0) self.assertEqual(y, xpected) def testException(self): @@ -248,8 +209,8 @@ class AbstractTest(unittest.TestCase): self.assertEqual(x.message, 'Xception') # TODO ensure same behavior for repr within generated python variants # ensure exception's repr method works - #x_repr = repr(x) - #self.assertEqual(x_repr, 'Xception(errorCode=1001, message=\'Xception\')') + # x_repr = repr(x) + # self.assertEqual(x_repr, 'Xception(errorCode=1001, message=\'Xception\')') try: self.client.testException('TException') @@ -280,31 +241,35 @@ class AbstractTest(unittest.TestCase): def testOneway(self): print('testOneway') start = time.time() - self.client.testOneway(1) # type is int, not float + self.client.testOneway(1) # type is int, not float end = time.time() self.assertTrue(end - start < 3, "oneway sleep took %f sec" % (end - start)) def testOnewayThenNormal(self): print('testOnewayThenNormal') - self.client.testOneway(1) # type is int, not float + self.client.testOneway(1) # type is int, not float self.assertEqual(self.client.testString('Python'), 'Python') class NormalBinaryTest(AbstractTest): - protocol_factory = TBinaryProtocol.TBinaryProtocolFactory() + def get_protocol(self, transport): + return TBinaryProtocol.TBinaryProtocolFactory().getProtocol(transport) class CompactTest(AbstractTest): - protocol_factory = TCompactProtocol.TCompactProtocolFactory() + def get_protocol(self, transport): + return TCompactProtocol.TCompactProtocolFactory().getProtocol(transport) class JSONTest(AbstractTest): - protocol_factory = TJSONProtocol.TJSONProtocolFactory() + def get_protocol(self, transport): + return TJSONProtocol.TJSONProtocolFactory().getProtocol(transport) class AcceleratedBinaryTest(AbstractTest): - protocol_factory = TBinaryProtocol.TBinaryProtocolAcceleratedFactory() + def get_protocol(self, transport): + return TBinaryProtocol.TBinaryProtocolAcceleratedFactory().getProtocol(transport) def suite(): @@ -328,8 +293,54 @@ class OwnArgsTestProgram(unittest.TestProgram): if args: self.testNames = args else: - self.testNames = (self.defaultTest,) + self.testNames = ([self.defaultTest]) self.createTests() if __name__ == "__main__": + parser = OptionParser() + parser.add_option('--libpydir', type='string', dest='libpydir', + help='include this directory in sys.path for locating library code') + parser.add_option('--genpydir', type='string', dest='genpydir', + default='gen-py', + help='include this directory in sys.path for locating generated code') + parser.add_option("--port", type="int", dest="port", + help="connect to server at port") + parser.add_option("--host", type="string", dest="host", + help="connect to server") + parser.add_option("--zlib", action="store_true", dest="zlib", + help="use zlib wrapper for compressed transport") + parser.add_option("--ssl", action="store_true", dest="ssl", + help="use SSL for encrypted transport") + parser.add_option("--http", dest="http_path", + help="Use the HTTP transport with the specified path") + parser.add_option('-v', '--verbose', action="store_const", + dest="verbose", const=2, + help="verbose output") + parser.add_option('-q', '--quiet', action="store_const", + dest="verbose", const=0, + help="minimal output") + parser.add_option('--protocol', dest="proto", type="string", + help="protocol to use, one of: accel, binary, compact, json") + parser.add_option('--transport', dest="trans", type="string", + help="transport to use, one of: buffered, framed") + parser.set_defaults(framed=False, http_path=None, verbose=1, host='localhost', port=9090, proto='binary') + options, args = parser.parse_args() + + sys.path.insert(0, os.path.join(SCRIPT_DIR, options.genpydir)) + if options.libpydir: + sys.path.insert(0, glob.glob(options.libpydir)[0]) + else: + sys.path.insert(0, glob.glob(DEFAULT_LIBDIR_GLOB)[0]) + + from ThriftTest import ThriftTest + from ThriftTest.ttypes import Xtruct, Xtruct2, Numberz, Xception, Xception2 + from thrift.Thrift import TException + from thrift.transport import TTransport + from thrift.transport import TSocket + from thrift.transport import THttpClient + from thrift.transport import TZlibTransport + from thrift.protocol import TBinaryProtocol + from thrift.protocol import TCompactProtocol + from thrift.protocol import TJSONProtocol + OwnArgsTestProgram(defaultTest="suite", testRunner=unittest.TextTestRunner(verbosity=1)) http://git-wip-us.apache.org/repos/asf/thrift/blob/a185d7e7/test/py/TestServer.py ---------------------------------------------------------------------- diff --git a/test/py/TestServer.py b/test/py/TestServer.py index bc221c0..4fa8894 100755 --- a/test/py/TestServer.py +++ b/test/py/TestServer.py @@ -26,55 +26,9 @@ 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(level=logging.DEBUG) - -parser = OptionParser() -parser.add_option('--genpydir', type='string', dest='genpydir', - default='gen-py', - help='include this local directory in sys.path for locating generated code') -parser.add_option("--port", type="int", dest="port", - help="port number for server to listen on") -parser.add_option("--zlib", action="store_true", dest="zlib", - help="use zlib wrapper for compressed transport") -parser.add_option("--ssl", action="store_true", dest="ssl", - help="use SSL for encrypted transport") -parser.add_option('-v', '--verbose', action="store_const", - dest="verbose", const=2, - help="verbose output") -parser.add_option('-q', '--quiet', action="store_const", - dest="verbose", const=0, - help="minimal output") -parser.add_option('--protocol', dest="proto", type="string", - help="protocol to use, one of: accel, binary, compact, json") -parser.add_option('--transport', dest="trans", type="string", - help="transport to use, one of: buffered, framed") -parser.set_defaults(port=9090, verbose=1, proto='binary') -options, args = parser.parse_args() - -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 * -from thrift.Thrift import TException -from thrift.transport import TTransport -from thrift.transport import TSocket -from thrift.transport import TZlibTransport -from thrift.protocol import TBinaryProtocol -from thrift.protocol import TCompactProtocol -from thrift.protocol import TJSONProtocol -from thrift.server import TServer, TNonblockingServer, THttpServer - -PROT_FACTORIES = { - 'binary': TBinaryProtocol.TBinaryProtocolFactory, - 'accel': TBinaryProtocol.TBinaryProtocolAcceleratedFactory, - 'compact': TCompactProtocol.TCompactProtocolFactory, - 'json': TJSONProtocol.TJSONProtocolFactory, -} +SCRIPT_DIR = os.path.abspath(os.path.dirname(__file__)) +ROOT_DIR = os.path.dirname(os.path.dirname(SCRIPT_DIR)) +DEFAULT_LIBDIR_GLOB = os.path.join(ROOT_DIR, 'lib', 'py', 'build', 'lib.*') class TestHandler(object): @@ -224,78 +178,133 @@ class TestHandler(object): byte_thing=arg0, i32_thing=arg1, i64_thing=arg2) -# set up the protocol factory form the --protocol option -pfactory_cls = PROT_FACTORIES.get(options.proto, None) -if pfactory_cls is None: - raise AssertionError('Unknown --protocol option: %s' % options.proto) -pfactory = pfactory_cls() - -# get the server type (TSimpleServer, TNonblockingServer, etc...) -if len(args) > 1: - raise AssertionError('Only one server type may be specified, not multiple types.') -server_type = args[0] - -# Set up the handler and processor objects -handler = TestHandler() -processor = ThriftTest.Processor(handler) - -# Handle THttpServer as a special case -if server_type == 'THttpServer': - server = THttpServer.THttpServer(processor, ('', options.port), pfactory) - server.serve() - sys.exit(0) - -# set up server transport and transport factory +def main(options): + # Print TServer log to stdout so that the test-runner can redirect it to log files + logging.basicConfig(level=logging.DEBUG) -abs_key_path = os.path.join(os.path.dirname(script_dir), 'keys', 'server.pem') - -host = None -if options.ssl: - from thrift.transport import TSSLSocket - transport = TSSLSocket.TSSLServerSocket(host, options.port, certfile=abs_key_path) -else: - transport = TSocket.TServerSocket(host, options.port) -tfactory = TTransport.TBufferedTransportFactory() -if options.trans == 'buffered': - tfactory = TTransport.TBufferedTransportFactory() -elif options.trans == 'framed': - tfactory = TTransport.TFramedTransportFactory() -elif options.trans == '': - raise AssertionError('Unknown --transport option: %s' % options.trans) -else: + # set up the protocol factory form the --protocol option + prot_factories = { + 'binary': TBinaryProtocol.TBinaryProtocolFactory, + 'accel': TBinaryProtocol.TBinaryProtocolAcceleratedFactory, + 'compact': TCompactProtocol.TCompactProtocolFactory, + 'json': TJSONProtocol.TJSONProtocolFactory, + } + pfactory_cls = prot_factories.get(options.proto, None) + if pfactory_cls is None: + raise AssertionError('Unknown --protocol option: %s' % options.proto) + pfactory = pfactory_cls() + + # get the server type (TSimpleServer, TNonblockingServer, etc...) + if len(args) > 1: + raise AssertionError('Only one server type may be specified, not multiple types.') + server_type = args[0] + + # Set up the handler and processor objects + handler = TestHandler() + processor = ThriftTest.Processor(handler) + + # Handle THttpServer as a special case + if server_type == 'THttpServer': + server = THttpServer.THttpServer(processor, ('', options.port), pfactory) + server.serve() + sys.exit(0) + + # set up server transport and transport factory + + abs_key_path = os.path.join(os.path.dirname(SCRIPT_DIR), 'keys', 'server.pem') + + host = None + if options.ssl: + from thrift.transport import TSSLSocket + transport = TSSLSocket.TSSLServerSocket(host, options.port, certfile=abs_key_path) + else: + transport = TSocket.TServerSocket(host, options.port) tfactory = TTransport.TBufferedTransportFactory() -# if --zlib, then wrap server transport, and use a different transport factory -if options.zlib: - transport = TZlibTransport.TZlibTransport(transport) # wrap with zlib - tfactory = TZlibTransport.TZlibTransportFactory() - -# do server-specific setup here: -if server_type == "TNonblockingServer": - server = TNonblockingServer.TNonblockingServer(processor, transport, inputProtocolFactory=pfactory) -elif server_type == "TProcessPoolServer": - import signal - 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.trans == 'buffered': + tfactory = TTransport.TBufferedTransportFactory() + elif options.trans == 'framed': + tfactory = TTransport.TFramedTransportFactory() + elif options.trans == '': + raise AssertionError('Unknown --transport option: %s' % options.trans) + else: + tfactory = TTransport.TBufferedTransportFactory() + # if --zlib, then wrap server transport, and use a different transport factory + if options.zlib: + transport = TZlibTransport.TZlibTransport(transport) # wrap with zlib + tfactory = TZlibTransport.TZlibTransportFactory() + + # do server-specific setup here: + if server_type == "TNonblockingServer": + server = TNonblockingServer.TNonblockingServer(processor, transport, inputProtocolFactory=pfactory) + elif server_type == "TProcessPoolServer": + import signal + 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: + logging.info('Terminating worker: %s' % worker) + worker.terminate() if options.verbose > 0: - logging.info('Terminating worker: %s' % worker) - worker.terminate() - if options.verbose > 0: - logging.info('Requesting server to stop()') - try: - server.stop() - except: - pass - signal.signal(signal.SIGALRM, clean_shutdown) - signal.alarm(4) - set_alarm() -else: - # look up server class dynamically to instantiate server - ServerClass = getattr(TServer, server_type) - server = ServerClass(processor, transport, tfactory, pfactory) -# enter server main loop -server.serve() + logging.info('Requesting server to stop()') + try: + server.stop() + except: + pass + signal.signal(signal.SIGALRM, clean_shutdown) + signal.alarm(4) + set_alarm() + else: + # look up server class dynamically to instantiate server + ServerClass = getattr(TServer, server_type) + server = ServerClass(processor, transport, tfactory, pfactory) + # enter server main loop + server.serve() + +if __name__ == '__main__': + parser = OptionParser() + parser.add_option('--libpydir', type='string', dest='libpydir', + help='include this directory to sys.path for locating library code') + parser.add_option('--genpydir', type='string', dest='genpydir', + default='gen-py', + help='include this directory to sys.path for locating generated code') + parser.add_option("--port", type="int", dest="port", + help="port number for server to listen on") + parser.add_option("--zlib", action="store_true", dest="zlib", + help="use zlib wrapper for compressed transport") + parser.add_option("--ssl", action="store_true", dest="ssl", + help="use SSL for encrypted transport") + parser.add_option('-v', '--verbose', action="store_const", + dest="verbose", const=2, + help="verbose output") + parser.add_option('-q', '--quiet', action="store_const", + dest="verbose", const=0, + help="minimal output") + parser.add_option('--protocol', dest="proto", type="string", + help="protocol to use, one of: accel, binary, compact, json") + parser.add_option('--transport', dest="trans", type="string", + help="transport to use, one of: buffered, framed") + parser.set_defaults(port=9090, verbose=1, proto='binary') + options, args = parser.parse_args() + + sys.path.insert(0, os.path.join(SCRIPT_DIR, options.genpydir)) + if options.libpydir: + sys.path.insert(0, glob.glob(options.libpydir)[0]) + else: + sys.path.insert(0, glob.glob(DEFAULT_LIBDIR_GLOB)[0]) + + from ThriftTest import ThriftTest + from ThriftTest.ttypes import Xtruct, Xception, Xception2, Insanity + from thrift.Thrift import TException + from thrift.transport import TTransport + from thrift.transport import TSocket + from thrift.transport import TZlibTransport + from thrift.protocol import TBinaryProtocol + from thrift.protocol import TCompactProtocol + from thrift.protocol import TJSONProtocol + from thrift.server import TServer, TNonblockingServer, THttpServer + + sys.exit(main(options)) http://git-wip-us.apache.org/repos/asf/thrift/blob/a185d7e7/test/tests.json ---------------------------------------------------------------------- diff --git a/test/tests.json b/test/tests.json index 0c35df2..afc7531 100644 --- a/test/tests.json +++ b/test/tests.json @@ -202,6 +202,45 @@ "workdir": "py" }, { + "comment": "Using 'python3' executable to test py2 and 3 at once", + "name": "py3", + "server": { + "delay": 1, + "extra_args": ["TSimpleServer"], + "command": [ + "python3", + "TestServer.py", + "--verbose", + "--libpydir=../../lib/py/build/lib", + "--genpydir=gen-py" + ] + }, + "client": { + "timeout": 10, + "command": [ + "python3", + "TestClient.py", + "--host=localhost", + "--libpydir=../../lib/py/build/lib", + "--genpydir=gen-py" + ] + }, + "transports": [ + "buffered", + "framed" + ], + "sockets": [ + "ip-ssl", + "ip" + ], + "protocols": [ + "compact", + "binary", + "json" + ], + "workdir": "py" + }, + { "name": "cpp", "server": { "delay": 2,
