blob: 89b74da8578fcf0ddf67296476fdeb04b16fb2d3 [file] [log] [blame]
Mark Slee57cc25e2007-02-28 21:43:54 +00001#!/usr/bin/env python
Mark Sleec9676562006-09-05 17:34:52 +00002
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#
Bryan Duxbury59d4efd2011-03-21 17:38:22 +000021from __future__ import division
Roger Meier85fb6de2012-11-02 00:05:42 +000022import sys, glob, time, os
23sys.path.insert(0, glob.glob(os.path.join(os.path.dirname(__file__),'../../lib/py/build/lib.*'))[0])
Bryan Duxbury59d4efd2011-03-21 17:38:22 +000024from optparse import OptionParser
Mark Sleec9676562006-09-05 17:34:52 +000025
Bryan Duxbury59d4efd2011-03-21 17:38:22 +000026parser = OptionParser()
Roger Meierf4eec7a2011-09-11 18:16:21 +000027parser.add_option('--genpydir', type='string', dest='genpydir',
28 default='gen-py',
29 help='include this local directory in sys.path for locating generated code')
Bryan Duxbury59d4efd2011-03-21 17:38:22 +000030parser.add_option("--port", type="int", dest="port",
31 help="port number for server to listen on")
Bryan Duxbury16066592011-03-22 18:06:04 +000032parser.add_option("--zlib", action="store_true", dest="zlib",
33 help="use zlib wrapper for compressed transport")
34parser.add_option("--ssl", action="store_true", dest="ssl",
35 help="use SSL for encrypted transport")
Roger Meier76150722014-05-31 22:22:07 +020036parser.add_option('-v', '--verbose', action="store_const",
Bryan Duxbury59d4efd2011-03-21 17:38:22 +000037 dest="verbose", const=2,
38 help="verbose output")
Roger Meier76150722014-05-31 22:22:07 +020039parser.add_option('-q', '--quiet', action="store_const",
Bryan Duxbury16066592011-03-22 18:06:04 +000040 dest="verbose", const=0,
41 help="minimal output")
Roger Meier76150722014-05-31 22:22:07 +020042parser.add_option('--protocol', dest="proto", type="string",
Roger Meier85fb6de2012-11-02 00:05:42 +000043 help="protocol to use, one of: accel, binary, compact, json")
Roger Meier76150722014-05-31 22:22:07 +020044parser.add_option('--transport', dest="trans", type="string",
45 help="transport to use, one of: buffered, framed")
Bryan Duxbury16066592011-03-22 18:06:04 +000046parser.set_defaults(port=9090, verbose=1, proto='binary')
Bryan Duxbury59d4efd2011-03-21 17:38:22 +000047options, args = parser.parse_args()
48
cdwijayarathna0d4072b2014-08-09 21:32:21 +053049script_dir = os.path.dirname(__file__) #<-- absolute dir the script is in
50sys.path.insert(0, os.path.join(script_dir, options.genpydir))
Roger Meierf4eec7a2011-09-11 18:16:21 +000051
jfarrelldbf2bb52014-07-09 23:37:12 -040052from ThriftTest import ThriftTest
Roger Meierf4eec7a2011-09-11 18:16:21 +000053from ThriftTest.ttypes import *
Roger Meier1f554e12013-01-05 20:38:35 +010054from thrift.Thrift import TException
Roger Meierf4eec7a2011-09-11 18:16:21 +000055from thrift.transport import TTransport
56from thrift.transport import TSocket
57from thrift.transport import TZlibTransport
58from thrift.protocol import TBinaryProtocol
59from thrift.protocol import TCompactProtocol
Roger Meier85fb6de2012-11-02 00:05:42 +000060from thrift.protocol import TJSONProtocol
Roger Meierf4eec7a2011-09-11 18:16:21 +000061from thrift.server import TServer, TNonblockingServer, THttpServer
62
63PROT_FACTORIES = {'binary': TBinaryProtocol.TBinaryProtocolFactory,
64 'accel': TBinaryProtocol.TBinaryProtocolAcceleratedFactory,
Roger Meier85fb6de2012-11-02 00:05:42 +000065 'compact': TCompactProtocol.TCompactProtocolFactory,
66 'json': TJSONProtocol.TJSONProtocolFactory}
Roger Meierf4eec7a2011-09-11 18:16:21 +000067
Mark Sleec9676562006-09-05 17:34:52 +000068class TestHandler:
69
70 def testVoid(self):
Bryan Duxbury16066592011-03-22 18:06:04 +000071 if options.verbose > 1:
Bryan Duxbury59d4efd2011-03-21 17:38:22 +000072 print 'testVoid()'
Mark Sleec9676562006-09-05 17:34:52 +000073
74 def testString(self, str):
Bryan Duxbury16066592011-03-22 18:06:04 +000075 if options.verbose > 1:
Bryan Duxbury59d4efd2011-03-21 17:38:22 +000076 print 'testString(%s)' % str
Mark Sleec9676562006-09-05 17:34:52 +000077 return str
78
Nobuaki Sukegawaa649e742015-09-21 13:53:25 +090079 def testBool(self, boolean):
80 if options.verbose > 1:
81 print 'testBool(%s)' % str(boolean).lower()
82 return boolean
83
Mark Sleec9676562006-09-05 17:34:52 +000084 def testByte(self, byte):
Bryan Duxbury16066592011-03-22 18:06:04 +000085 if options.verbose > 1:
Bryan Duxbury59d4efd2011-03-21 17:38:22 +000086 print 'testByte(%d)' % byte
Mark Sleec9676562006-09-05 17:34:52 +000087 return byte
88
Mark Sleec98d0502006-09-06 02:42:25 +000089 def testI16(self, i16):
Bryan Duxbury16066592011-03-22 18:06:04 +000090 if options.verbose > 1:
Bryan Duxbury59d4efd2011-03-21 17:38:22 +000091 print 'testI16(%d)' % i16
Mark Sleec98d0502006-09-06 02:42:25 +000092 return i16
93
94 def testI32(self, i32):
Bryan Duxbury16066592011-03-22 18:06:04 +000095 if options.verbose > 1:
Bryan Duxbury59d4efd2011-03-21 17:38:22 +000096 print 'testI32(%d)' % i32
Mark Sleec98d0502006-09-06 02:42:25 +000097 return i32
98
99 def testI64(self, i64):
Bryan Duxbury16066592011-03-22 18:06:04 +0000100 if options.verbose > 1:
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000101 print 'testI64(%d)' % i64
Mark Sleec98d0502006-09-06 02:42:25 +0000102 return i64
103
104 def testDouble(self, dub):
Bryan Duxbury16066592011-03-22 18:06:04 +0000105 if options.verbose > 1:
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000106 print 'testDouble(%f)' % dub
Mark Sleec98d0502006-09-06 02:42:25 +0000107 return dub
108
Jens Geyer8bcfdd92014-12-14 03:14:26 +0100109 def testBinary(self, thing):
110 if options.verbose > 1:
111 print 'testBinary()' # TODO: hex output
112 return thring
113
Mark Sleec98d0502006-09-06 02:42:25 +0000114 def testStruct(self, thing):
Bryan Duxbury16066592011-03-22 18:06:04 +0000115 if options.verbose > 1:
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000116 print 'testStruct({%s, %d, %d, %d})' % (thing.string_thing, thing.byte_thing, thing.i32_thing, thing.i64_thing)
Mark Sleec98d0502006-09-06 02:42:25 +0000117 return thing
118
Roger Meier1f554e12013-01-05 20:38:35 +0100119 def testException(self, arg):
120 #if options.verbose > 1:
121 print 'testException(%s)' % arg
122 if arg == 'Xception':
123 raise Xception(errorCode=1001, message=arg)
124 elif arg == 'TException':
125 raise TException(message='This is a TException')
126
127 def testMultiException(self, arg0, arg1):
Bryan Duxbury16066592011-03-22 18:06:04 +0000128 if options.verbose > 1:
Roger Meier1f554e12013-01-05 20:38:35 +0100129 print 'testMultiException(%s, %s)' % (arg0, arg1)
130 if arg0 == 'Xception':
131 raise Xception(errorCode=1001, message='This is an Xception')
132 elif arg0 == 'Xception2':
133 raise Xception2(
134 errorCode=2002,
135 struct_thing=Xtruct(string_thing='This is an Xception2'))
136 return Xtruct(string_thing=arg1)
Mark Sleec9676562006-09-05 17:34:52 +0000137
David Reiss6ce401d2009-03-24 20:01:58 +0000138 def testOneway(self, seconds):
Bryan Duxbury16066592011-03-22 18:06:04 +0000139 if options.verbose > 1:
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000140 print 'testOneway(%d) => sleeping...' % seconds
141 time.sleep(seconds / 3) # be quick
Bryan Duxbury16066592011-03-22 18:06:04 +0000142 if options.verbose > 1:
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000143 print 'done sleeping'
David Reissdb893b62008-02-18 02:11:48 +0000144
David Reiss74421272008-11-07 23:09:31 +0000145 def testNest(self, thing):
Bryan Duxbury16066592011-03-22 18:06:04 +0000146 if options.verbose > 1:
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000147 print 'testNest(%s)' % thing
David Reiss74421272008-11-07 23:09:31 +0000148 return thing
149
150 def testMap(self, thing):
Bryan Duxbury16066592011-03-22 18:06:04 +0000151 if options.verbose > 1:
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000152 print 'testMap(%s)' % thing
David Reiss74421272008-11-07 23:09:31 +0000153 return thing
154
155 def testSet(self, thing):
Bryan Duxbury16066592011-03-22 18:06:04 +0000156 if options.verbose > 1:
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000157 print 'testSet(%s)' % thing
David Reiss74421272008-11-07 23:09:31 +0000158 return thing
159
160 def testList(self, thing):
Bryan Duxbury16066592011-03-22 18:06:04 +0000161 if options.verbose > 1:
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000162 print 'testList(%s)' % thing
David Reiss74421272008-11-07 23:09:31 +0000163 return thing
164
165 def testEnum(self, thing):
Bryan Duxbury16066592011-03-22 18:06:04 +0000166 if options.verbose > 1:
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000167 print 'testEnum(%s)' % thing
David Reiss74421272008-11-07 23:09:31 +0000168 return thing
169
170 def testTypedef(self, thing):
Bryan Duxbury16066592011-03-22 18:06:04 +0000171 if options.verbose > 1:
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000172 print 'testTypedef(%s)' % thing
David Reiss74421272008-11-07 23:09:31 +0000173 return thing
174
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000175 def testMapMap(self, thing):
Bryan Duxbury16066592011-03-22 18:06:04 +0000176 if options.verbose > 1:
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000177 print 'testMapMap(%s)' % thing
Roger Meier1f554e12013-01-05 20:38:35 +0100178 return {thing: {thing: thing}}
179
180 def testInsanity(self, argument):
181 if options.verbose > 1:
182 print 'testInsanity(%s)' % argument
183 return {123489: {Numberz.ONE:argument}}
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000184
185 def testMulti(self, arg0, arg1, arg2, arg3, arg4, arg5):
Bryan Duxbury16066592011-03-22 18:06:04 +0000186 if options.verbose > 1:
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000187 print 'testMulti(%s)' % [arg0, arg1, arg2, arg3, arg4, arg5]
Roger Meier1f554e12013-01-05 20:38:35 +0100188 return Xtruct(string_thing='Hello2',
189 byte_thing=arg0, i32_thing=arg1, i64_thing=arg2)
190
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000191
Roger Meier76150722014-05-31 22:22:07 +0200192# set up the protocol factory form the --protocol option
Bryan Duxbury16066592011-03-22 18:06:04 +0000193pfactory_cls = PROT_FACTORIES.get(options.proto, None)
194if pfactory_cls is None:
Roger Meier76150722014-05-31 22:22:07 +0200195 raise AssertionError('Unknown --protocol option: %s' % options.proto)
Bryan Duxbury16066592011-03-22 18:06:04 +0000196pfactory = pfactory_cls()
197
198# get the server type (TSimpleServer, TNonblockingServer, etc...)
199if len(args) > 1:
200 raise AssertionError('Only one server type may be specified, not multiple types.')
201server_type = args[0]
202
203# Set up the handler and processor objects
jfarrelldbf2bb52014-07-09 23:37:12 -0400204handler = TestHandler()
205processor = ThriftTest.Processor(handler)
David Reissbcaa2ad2008-06-10 22:55:26 +0000206
Bryan Duxbury16066592011-03-22 18:06:04 +0000207# Handle THttpServer as a special case
208if server_type == 'THttpServer':
209 server =THttpServer.THttpServer(processor, ('', options.port), pfactory)
210 server.serve()
211 sys.exit(0)
212
213# set up server transport and transport factory
Roger Meier76150722014-05-31 22:22:07 +0200214
Roger Meier76150722014-05-31 22:22:07 +0200215rel_path = "../keys/server.pem"
216abs_key_path = os.path.join(script_dir, rel_path)
217
Bryan Duxbury16066592011-03-22 18:06:04 +0000218host = None
219if options.ssl:
220 from thrift.transport import TSSLSocket
Roger Meier76150722014-05-31 22:22:07 +0200221 transport = TSSLSocket.TSSLServerSocket(host, options.port, certfile=abs_key_path)
David Reiss74421272008-11-07 23:09:31 +0000222else:
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000223 transport = TSocket.TServerSocket(host, options.port)
Bryan Duxbury16066592011-03-22 18:06:04 +0000224tfactory = TTransport.TBufferedTransportFactory()
Roger Meier76150722014-05-31 22:22:07 +0200225if options.trans == 'buffered':
226 tfactory = TTransport.TBufferedTransportFactory()
227elif options.trans == 'framed':
228 tfactory = TTransport.TFramedTransportFactory()
229elif options.trans == '':
230 raise AssertionError('Unknown --transport option: %s' % options.trans)
231else:
232 tfactory = TTransport.TBufferedTransportFactory()
Bryan Duxbury16066592011-03-22 18:06:04 +0000233# if --zlib, then wrap server transport, and use a different transport factory
234if options.zlib:
235 transport = TZlibTransport.TZlibTransport(transport) # wrap with zlib
236 tfactory = TZlibTransport.TZlibTransportFactory()
237
238# do server-specific setup here:
239if server_type == "TNonblockingServer":
240 server = TNonblockingServer.TNonblockingServer(processor, transport, inputProtocolFactory=pfactory)
241elif server_type == "TProcessPoolServer":
242 import signal
243 from thrift.server import TProcessPoolServer
244 server = TProcessPoolServer.TProcessPoolServer(processor, transport, tfactory, pfactory)
245 server.setNumWorkers(5)
246 def set_alarm():
247 def clean_shutdown(signum, frame):
248 for worker in server.workers:
249 if options.verbose > 0:
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000250 print 'Terminating worker: %s' % worker
Bryan Duxbury16066592011-03-22 18:06:04 +0000251 worker.terminate()
252 if options.verbose > 0:
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000253 print 'Requesting server to stop()'
Roger Meierf4eec7a2011-09-11 18:16:21 +0000254 try:
255 server.stop()
256 except:
257 pass
Bryan Duxbury16066592011-03-22 18:06:04 +0000258 signal.signal(signal.SIGALRM, clean_shutdown)
Jens Geyerf7d327a2015-07-25 15:44:20 +0200259 signal.alarm(4)
Bryan Duxbury16066592011-03-22 18:06:04 +0000260 set_alarm()
261else:
262 # look up server class dynamically to instantiate server
263 ServerClass = getattr(TServer, server_type)
264 server = ServerClass(processor, transport, tfactory, pfactory)
265# enter server main loop
Mark Slee794993d2006-09-20 01:56:10 +0000266server.serve()