diff options
author | Nobuaki Sukegawa <nsuke@apache.org> | 2015-11-08 23:43:55 +0900 |
---|---|---|
committer | Nobuaki Sukegawa <nsuke@apache.org> | 2015-11-23 21:24:24 +0900 |
commit | cacce2f1d503b7e98842308852237af53180fd87 (patch) | |
tree | 6790136242a09a061028f713ae7a1419bdbbdd0c /test/py | |
parent | 2de2700c34bde8d7576da148852c43a32c11e94a (diff) | |
download | thrift-cacce2f1d503b7e98842308852237af53180fd87.tar.gz |
THRIFT-3440 Python make check takes too much time
Client: Test Python
Patch: Nobuaki Sukegawa
This closes #711
Diffstat (limited to 'test/py')
-rwxr-xr-x | test/py/RunClientServer.py | 319 | ||||
-rwxr-xr-x | test/py/SerializationTest.py | 17 | ||||
-rw-r--r-- | test/py/TSimpleJSONProtocolTest.py | 21 | ||||
-rwxr-xr-x | test/py/TestEof.py | 16 | ||||
-rwxr-xr-x | test/py/TestSocket.py | 26 | ||||
-rwxr-xr-x | test/py/TestSyntax.py | 9 |
6 files changed, 228 insertions, 180 deletions
diff --git a/test/py/RunClientServer.py b/test/py/RunClientServer.py index 7224bac91..fa2a26411 100755 --- a/test/py/RunClientServer.py +++ b/test/py/RunClientServer.py @@ -21,108 +21,92 @@ from __future__ import division from __future__ import print_function -import time +import copy +import glob +import os +import signal import socket import subprocess import sys -import os -import signal +import time from optparse import OptionParser -parser = OptionParser() -parser.add_option('--genpydirs', type='string', dest='genpydirs', - default='default,slots,newstyle,newstyleslots,dynamic,dynamicslots', - help='directory extensions for generated code, used as suffixes for \"gen-py-*\" added sys.path for individual tests') -parser.add_option("--port", type="int", dest="port", default=9090, - help="port number for server to listen on") -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.set_defaults(verbose=1) -options, args = parser.parse_args() - -generated_dirs = [] -for gp_dir in options.genpydirs.split(','): - generated_dirs.append('gen-py-%s' % (gp_dir)) - -SCRIPTS = ['TSimpleJSONProtocolTest.py', - 'SerializationTest.py', - 'TestEof.py', - 'TestSyntax.py', - 'TestSocket.py'] +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.*') +DEFAULT_LIBDIR_PY3 = os.path.join(ROOT_DIR, 'lib', 'py', 'build', 'lib') + +SCRIPTS = [ + 'TSimpleJSONProtocolTest.py', + 'SerializationTest.py', + 'TestEof.py', + 'TestSyntax.py', + 'TestSocket.py', +] FRAMED = ["TNonblockingServer"] SKIP_ZLIB = ['TNonblockingServer', 'THttpServer'] SKIP_SSL = ['TNonblockingServer', 'THttpServer'] EXTRA_DELAY = dict(TProcessPoolServer=5.5) -PROTOS= [ - 'accel', - 'binary', - 'compact', - 'json'] +PROTOS = [ + 'accel', + 'binary', + 'compact', + 'json', +] SERVERS = [ "TSimpleServer", "TThreadedServer", "TThreadPoolServer", - "TProcessPoolServer", # new! + "TProcessPoolServer", "TForkingServer", "TNonblockingServer", - "THttpServer" ] - -# Test for presence of multiprocessing module, and if it is not present, then -# remove it from the list of available servers. -try: - import multiprocessing -except: - print('Warning: the multiprocessing module is unavailable. Skipping tests for TProcessPoolServer') - SERVERS.remove('TProcessPoolServer') - -try: - import ssl -except: - print('Warning, no ssl module available. Skipping all SSL tests.') - SKIP_SSL.extend(SERVERS) - -# commandline permits a single class name to be specified to override SERVERS=[...] -if len(args) == 1: - if args[0] in SERVERS: - SERVERS = args - else: - print('Unavailable server type "%s", please choose one of: %s' % (args[0], SERVERS)) - sys.exit(0) + "THttpServer", +] def relfile(fname): - return os.path.join(os.path.dirname(__file__), fname) + return os.path.join(SCRIPT_DIR, fname) -def runScriptTest(genpydir, script): - script_args = [sys.executable, relfile(script) ] - script_args.append('--genpydir=%s' % genpydir) - serverproc = subprocess.Popen(script_args) + +def setup_pypath(dirs): + env = copy.copy(os.environ) + pypath = env.get('PYTHONPATH', None) + if pypath: + dirs.append(pypath) + env['PYTHONPATH'] = ':'.join(dirs) + return env + + +def runScriptTest(libdir, genpydir, script): + env = setup_pypath([libdir, genpydir]) + script_args = [sys.executable, relfile(script)] print('\nTesting script: %s\n----' % (' '.join(script_args))) - ret = subprocess.call(script_args) + ret = subprocess.call(script_args, env=env) if ret != 0: + print('*** FAILED ***', file=sys.stderr) + print('LIBDIR: %s' % libdir, file=sys.stderr) + print('PY_GEN: %s' % genpydir, file=sys.stderr) + print('SCRIPT: %s' % script, file=sys.stderr) raise Exception("Script subprocess failed, retcode=%d, args: %s" % (ret, ' '.join(script_args))) -def runServiceTest(genpydir, server_class, proto, port, use_zlib, use_ssl): + +def runServiceTest(libdir, genpydir, server_class, proto, port, use_zlib, use_ssl, verbose): + env = setup_pypath([libdir, genpydir]) # Build command line arguments - server_args = [sys.executable, relfile('TestServer.py') ] - cli_args = [sys.executable, relfile('TestClient.py') ] + server_args = [sys.executable, relfile('TestServer.py')] + cli_args = [sys.executable, relfile('TestClient.py')] for which in (server_args, cli_args): - which.append('--genpydir=%s' % genpydir) - which.append('--protocol=%s' % proto) # accel, binary or compact - which.append('--port=%d' % port) # default to 9090 + which.append('--protocol=%s' % proto) # accel, binary, compact or json + which.append('--port=%d' % port) # default to 9090 if use_zlib: which.append('--zlib') if use_ssl: which.append('--ssl') - if options.verbose == 0: + if verbose == 0: which.append('-q') - if options.verbose == 2: + if verbose == 2: which.append('-v') # server-specific option to select server class server_args.append(server_class) @@ -133,14 +117,14 @@ def runServiceTest(genpydir, server_class, proto, port, use_zlib, use_ssl): cli_args.append('--transport=buffered') if server_class == 'THttpServer': cli_args.append('--http=/') - if options.verbose > 0: + if verbose > 0: print('Testing server %s: %s' % (server_class, ' '.join(server_args))) - serverproc = subprocess.Popen(server_args) + serverproc = subprocess.Popen(server_args, env=env) def ensureServerAlive(): if serverproc.poll() is not None: print(('FAIL: Server process (%s) failed with retcode %d') - % (' '.join(server_args), serverproc.returncode)) + % (' '.join(server_args), serverproc.returncode)) raise Exception('Server subprocess %s died, args: %s' % (server_class, ' '.join(server_args))) @@ -161,55 +145,166 @@ def runServiceTest(genpydir, server_class, proto, port, use_zlib, use_ssl): sock.close() try: - if options.verbose > 0: + if verbose > 0: print('Testing client: %s' % (' '.join(cli_args))) - ret = subprocess.call(cli_args) + ret = subprocess.call(cli_args, env=env) if ret != 0: + print('*** FAILED ***', file=sys.stderr) + print('LIBDIR: %s' % libdir, file=sys.stderr) + print('PY_GEN: %s' % genpydir, file=sys.stderr) raise Exception("Client subprocess failed, retcode=%d, args: %s" % (ret, ' '.join(cli_args))) finally: # check that server didn't die ensureServerAlive() extra_sleep = EXTRA_DELAY.get(server_class, 0) - if extra_sleep > 0 and options.verbose > 0: + if extra_sleep > 0 and verbose > 0: print('Giving %s (proto=%s,zlib=%s,ssl=%s) an extra %d seconds for child' - 'processes to terminate via alarm' - % (server_class, proto, use_zlib, use_ssl, extra_sleep)) + 'processes to terminate via alarm' + % (server_class, proto, use_zlib, use_ssl, extra_sleep)) time.sleep(extra_sleep) os.kill(serverproc.pid, signal.SIGKILL) serverproc.wait() -test_count = 0 -# run tests without a client/server first -print('----------------') -print(' Executing individual test scripts with various generated code directories') -print(' Directories to be tested: ' + ', '.join(generated_dirs)) -print(' Scripts to be tested: ' + ', '.join(SCRIPTS)) -print('----------------') -for genpydir in generated_dirs: - for script in SCRIPTS: - runScriptTest(genpydir, script) - -print('----------------') -print(' Executing Client/Server tests with various generated code directories') -print(' Servers to be tested: ' + ', '.join(SERVERS)) -print(' Directories to be tested: ' + ', '.join(generated_dirs)) -print(' Protocols to be tested: ' + ', '.join(PROTOS)) -print(' Options to be tested: ZLIB(yes/no), SSL(yes/no)') -print('----------------') -for try_server in SERVERS: + +class TestCases(object): + def __init__(self, libdir, port, gendirs, servers, verbose): + self.libdir = libdir + self.port = port + self.verbose = verbose + self.gendirs = gendirs + self.servers = servers + + def default_conf(self): + return { + 'gendir': self.gendirs[0], + 'server': self.servers[0], + 'proto': PROTOS[0], + 'zlib': False, + 'ssl': False, + } + + def run(self, conf, test_count): + with_zlib = conf['zlib'] + with_ssl = conf['ssl'] + try_server = conf['server'] + try_proto = conf['proto'] + genpydir = conf['gendir'] + # skip any servers that don't work with the Zlib transport + if with_zlib and try_server in SKIP_ZLIB: + return False + # skip any servers that don't work with SSL + if with_ssl and try_server in SKIP_SSL: + return False + if self.verbose > 0: + print('\nTest run #%d: (includes %s) Server=%s, Proto=%s, zlib=%s, SSL=%s' + % (test_count, genpydir, try_server, try_proto, with_zlib, with_ssl)) + runServiceTest(self.libdir, genpydir, try_server, try_proto, self.port, with_zlib, with_ssl, self.verbose) + if self.verbose > 0: + print('OK: Finished (includes %s) %s / %s proto / zlib=%s / SSL=%s. %d combinations tested.' + % (genpydir, try_server, try_proto, with_zlib, with_ssl, test_count)) + return True + + def test_feature(self, name, values): + test_count = 0 + conf = self.default_conf() + for try_server in values: + conf[name] = try_server + if self.run(conf, test_count): + test_count += 1 + return test_count + + def run_all_tests(self): + test_count = 0 + for try_server in self.servers: + for genpydir in self.gendirs: + for try_proto in PROTOS: + for with_zlib in (False, True): + # skip any servers that don't work with the Zlib transport + if with_zlib and try_server in SKIP_ZLIB: + continue + for with_ssl in (False, True): + # skip any servers that don't work with SSL + if with_ssl and try_server in SKIP_SSL: + continue + test_count += 1 + if self.verbose > 0: + print('\nTest run #%d: (includes %s) Server=%s, Proto=%s, zlib=%s, SSL=%s' + % (test_count, genpydir, try_server, try_proto, with_zlib, with_ssl)) + runServiceTest(self.libdir, genpydir, try_server, try_proto, self.port, with_zlib, with_ssl) + if self.verbose > 0: + print('OK: Finished (includes %s) %s / %s proto / zlib=%s / SSL=%s. %d combinations tested.' + % (genpydir, try_server, try_proto, with_zlib, with_ssl, test_count)) + return test_count + + +def default_libdir(): + if sys.version_info[0] == 2: + return glob.glob(DEFAULT_LIBDIR_GLOB)[0] + else: + return DEFAULT_LIBDIR_PY3 + + +def main(): + parser = OptionParser() + parser.add_option('--all', action="store_true", dest='all') + parser.add_option('--genpydirs', type='string', dest='genpydirs', + default='default,slots,newstyle,newstyleslots,dynamic,dynamicslots', + help='directory extensions for generated code, used as suffixes for \"gen-py-*\" added sys.path for individual tests') + parser.add_option("--port", type="int", dest="port", default=9090, + help="port number for server to listen on") + 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('-L', '--libdir', dest="libdir", default=default_libdir(), + help="directory path that contains Thrift Python library") + parser.set_defaults(verbose=1) + options, args = parser.parse_args() + + generated_dirs = [] + for gp_dir in options.genpydirs.split(','): + generated_dirs.append('gen-py-%s' % (gp_dir)) + + # commandline permits a single class name to be specified to override SERVERS=[...] + servers = SERVERS + if len(args) == 1: + if args[0] in SERVERS: + servers = args + else: + print('Unavailable server type "%s", please choose one of: %s' % (args[0], servers)) + sys.exit(0) + + tests = TestCases(options.libdir, options.port, generated_dirs, servers, options.verbose) + + # run tests without a client/server first + print('----------------') + print(' Executing individual test scripts with various generated code directories') + print(' Directories to be tested: ' + ', '.join(generated_dirs)) + print(' Scripts to be tested: ' + ', '.join(SCRIPTS)) + print('----------------') for genpydir in generated_dirs: - for try_proto in PROTOS: - for with_zlib in (False, True): - # skip any servers that don't work with the Zlib transport - if with_zlib and try_server in SKIP_ZLIB: - continue - for with_ssl in (False, True): - # skip any servers that don't work with SSL - if with_ssl and try_server in SKIP_SSL: - continue - test_count += 1 - if options.verbose > 0: - print('\nTest run #%d: (includes %s) Server=%s, Proto=%s, zlib=%s, SSL=%s' % (test_count, genpydir, try_server, try_proto, with_zlib, with_ssl)) - runServiceTest(genpydir, try_server, try_proto, options.port, with_zlib, with_ssl) - if options.verbose > 0: - print('OK: Finished (includes %s) %s / %s proto / zlib=%s / SSL=%s. %d combinations tested.' % (genpydir, try_server, try_proto, with_zlib, with_ssl, test_count)) + for script in SCRIPTS: + runScriptTest(options.libdir, genpydir, script) + + print('----------------') + print(' Executing Client/Server tests with various generated code directories') + print(' Servers to be tested: ' + ', '.join(servers)) + print(' Directories to be tested: ' + ', '.join(generated_dirs)) + print(' Protocols to be tested: ' + ', '.join(PROTOS)) + print(' Options to be tested: ZLIB(yes/no), SSL(yes/no)') + print('----------------') + + if options.all: + tests.run_all_tests() + else: + tests.test_feature('gendir', generated_dirs) + tests.test_feature('server', servers) + tests.test_feature('proto', PROTOS) + tests.test_feature('zlib', [False, True]) + tests.test_feature('ssl', [False, True]) + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/test/py/SerializationTest.py b/test/py/SerializationTest.py index 29f36564b..99e0393b4 100755 --- a/test/py/SerializationTest.py +++ b/test/py/SerializationTest.py @@ -19,23 +19,13 @@ # under the License. # -import sys, glob -from optparse import OptionParser -parser = OptionParser() -parser.add_option('--genpydir', type='string', dest='genpydir', default='gen-py') -options, args = parser.parse_args() -del sys.argv[1:] # clean up hack so unittest doesn't complain -sys.path.insert(0, options.genpydir) -sys.path.insert(0, glob.glob('../../lib/py/build/lib*')[0]) - from ThriftTest.ttypes import * from DebugProtoTest.ttypes import CompactProtoTestStruct, Empty from thrift.transport import TTransport -from thrift.transport import TSocket from thrift.protocol import TBinaryProtocol, TCompactProtocol, TJSONProtocol from thrift.TSerialization import serialize, deserialize import unittest -import time + class AbstractTest(unittest.TestCase): @@ -277,18 +267,23 @@ class AbstractTest(unittest.TestCase): for value in bad_values: self.assertRaises(Exception, self._serialize, value) + class NormalBinaryTest(AbstractTest): protocol_factory = TBinaryProtocol.TBinaryProtocolFactory() + class AcceleratedBinaryTest(AbstractTest): protocol_factory = TBinaryProtocol.TBinaryProtocolAcceleratedFactory() + class CompactProtocolTest(AbstractTest): protocol_factory = TCompactProtocol.TCompactProtocolFactory() + class JSONProtocolTest(AbstractTest): protocol_factory = TJSONProtocol.TJSONProtocolFactory() + class AcceleratedFramedTest(unittest.TestCase): def testSplit(self): """Test FramedTransport and BinaryProtocolAccelerated diff --git a/test/py/TSimpleJSONProtocolTest.py b/test/py/TSimpleJSONProtocolTest.py index b8db93296..1ed8c1574 100644 --- a/test/py/TSimpleJSONProtocolTest.py +++ b/test/py/TSimpleJSONProtocolTest.py @@ -19,17 +19,7 @@ # under the License. # -import sys -import glob -from optparse import OptionParser -parser = OptionParser() -parser.add_option('--genpydir', type='string', dest='genpydir', default='gen-py') -options, args = parser.parse_args() -del sys.argv[1:] # clean up hack so unittest doesn't complain -sys.path.insert(0, options.genpydir) -sys.path.insert(0, glob.glob('../../lib/py/build/lib*')[0]) - -from ThriftTest.ttypes import * +from ThriftTest.ttypes import Bonk, VersioningTestV1, VersioningTestV2 from thrift.protocol import TJSONProtocol from thrift.transport import TTransport @@ -40,7 +30,7 @@ import unittest class SimpleJSONProtocolTest(unittest.TestCase): protocol_factory = TJSONProtocol.TSimpleJSONProtocolFactory() - def _assertDictEqual(self, a ,b, msg=None): + def _assertDictEqual(self, a, b, msg=None): if hasattr(self, 'assertDictEqual'): # assertDictEqual only in Python 2.7. Depends on your machine. self.assertDictEqual(a, b, msg) @@ -89,9 +79,9 @@ class SimpleJSONProtocolTest(unittest.TestCase): newlong=4, newdouble=5.0, newstruct=Bonk(message="Hello!", type=123), - newlist=[7,8,9], - newset=set([42,1,8]), - newmap={1:2,2:3}, + newlist=[7, 8, 9], + newset=set([42, 1, 8]), + newmap={1: 2, 2: 3}, newstring="Hola!", end_in_both=54321) expected = dict(begin_in_both=v2obj.begin_in_both, @@ -116,4 +106,3 @@ class SimpleJSONProtocolTest(unittest.TestCase): if __name__ == '__main__': unittest.main() - diff --git a/test/py/TestEof.py b/test/py/TestEof.py index 7677de817..661463822 100755 --- a/test/py/TestEof.py +++ b/test/py/TestEof.py @@ -19,23 +19,12 @@ # under the License. # -import sys, glob -from optparse import OptionParser -parser = OptionParser() -parser.add_option('--genpydir', type='string', dest='genpydir', default='gen-py') -options, args = parser.parse_args() -del sys.argv[1:] # clean up hack so unittest doesn't complain -sys.path.insert(0, options.genpydir) -sys.path.insert(0, glob.glob('../../lib/py/build/lib*')[0]) - -from ThriftTest import ThriftTest -from ThriftTest.ttypes import * +from ThriftTest.ttypes import Xtruct from thrift.transport import TTransport -from thrift.transport import TSocket from thrift.protocol import TBinaryProtocol from thrift.protocol import TCompactProtocol import unittest -import time + class TestEof(unittest.TestCase): @@ -126,6 +115,7 @@ class TestEof(unittest.TestCase): self.eofTestHelper(TCompactProtocol.TCompactProtocolFactory()) self.eofTestHelperStress(TCompactProtocol.TCompactProtocolFactory()) + def suite(): suite = unittest.TestSuite() loader = unittest.TestLoader() diff --git a/test/py/TestSocket.py b/test/py/TestSocket.py index 55e4996e8..a01be85ac 100755 --- a/test/py/TestSocket.py +++ b/test/py/TestSocket.py @@ -19,25 +19,12 @@ # under the License. # -import sys, glob -from optparse import OptionParser -parser = OptionParser() -parser.add_option('--genpydir', type='string', dest='genpydir', default='gen-py') -options, args = parser.parse_args() -del sys.argv[1:] # clean up hack so unittest doesn't complain -sys.path.insert(0, options.genpydir) -sys.path.insert(0, glob.glob('../../lib/py/build/lib*')[0]) - -from ThriftTest import ThriftTest -from ThriftTest.ttypes import * -from thrift.transport import TTransport from thrift.transport import TSocket -from thrift.protocol import TBinaryProtocol import unittest import time import socket import random -from optparse import OptionParser + class TimeoutTest(unittest.TestCase): def setUp(self): @@ -80,10 +67,11 @@ class TimeoutTest(unittest.TestCase): except: self.assert_(time.time() - starttime < 5.0) -suite = unittest.TestSuite() -loader = unittest.TestLoader() +if __name__ == '__main__': + suite = unittest.TestSuite() + loader = unittest.TestLoader() -suite.addTest(loader.loadTestsFromTestCase(TimeoutTest)) + suite.addTest(loader.loadTestsFromTestCase(TimeoutTest)) -testRunner = unittest.TextTestRunner(verbosity=2) -testRunner.run(suite) + testRunner = unittest.TextTestRunner(verbosity=2) + testRunner.run(suite) diff --git a/test/py/TestSyntax.py b/test/py/TestSyntax.py index cdf0e0da0..c83f40e53 100755 --- a/test/py/TestSyntax.py +++ b/test/py/TestSyntax.py @@ -19,15 +19,6 @@ # under the License. # -import sys, glob -from optparse import OptionParser -parser = OptionParser() -parser.add_option('--genpydir', type='string', dest='genpydir', default='gen-py') -options, args = parser.parse_args() -del sys.argv[1:] # clean up hack so unittest doesn't complain -sys.path.insert(0, options.genpydir) -sys.path.insert(0, glob.glob('../../lib/py/build/lib*')[0]) - # Just import these generated files to make sure they are syntactically valid from DebugProtoTest import EmptyService from DebugProtoTest import Inherited |