blob: fa627650f1d203ae6f02e4025f6b380d1853439a [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
David Reissdb893b62008-02-18 02:11:48 +000022import sys, glob, time
Mark Slee5299a952007-10-05 00:13:24 +000023sys.path.insert(0, './gen-py')
24sys.path.insert(0, glob.glob('../../lib/py/build/lib.*')[0])
Bryan Duxbury59d4efd2011-03-21 17:38:22 +000025from optparse import OptionParser
Mark Sleec9676562006-09-05 17:34:52 +000026
Mark Slee57cc25e2007-02-28 21:43:54 +000027from ThriftTest import ThriftTest
28from ThriftTest.ttypes import *
Mark Sleed788b2e2006-09-07 01:26:35 +000029from thrift.transport import TTransport
Mark Sleec9676562006-09-05 17:34:52 +000030from thrift.transport import TSocket
Bryan Duxbury16066592011-03-22 18:06:04 +000031from thrift.transport import TZlibTransport
Mark Sleec9676562006-09-05 17:34:52 +000032from thrift.protocol import TBinaryProtocol
Bryan Duxbury59d4efd2011-03-21 17:38:22 +000033from thrift.protocol import TCompactProtocol
David Reissf78ec2b2009-01-31 21:59:32 +000034from thrift.server import TServer, TNonblockingServer, THttpServer
Mark Sleec9676562006-09-05 17:34:52 +000035
Bryan Duxbury16066592011-03-22 18:06:04 +000036PROT_FACTORIES = {'binary': TBinaryProtocol.TBinaryProtocolFactory,
37 'accel': TBinaryProtocol.TBinaryProtocolAcceleratedFactory,
38 'compact': TCompactProtocol.TCompactProtocolFactory}
39
Bryan Duxbury59d4efd2011-03-21 17:38:22 +000040parser = OptionParser()
Bryan Duxbury59d4efd2011-03-21 17:38:22 +000041parser.add_option("--port", type="int", dest="port",
42 help="port number for server to listen on")
Bryan Duxbury16066592011-03-22 18:06:04 +000043parser.add_option("--zlib", action="store_true", dest="zlib",
44 help="use zlib wrapper for compressed transport")
45parser.add_option("--ssl", action="store_true", dest="ssl",
46 help="use SSL for encrypted transport")
Bryan Duxbury59d4efd2011-03-21 17:38:22 +000047parser.add_option('-v', '--verbose', action="store_const",
48 dest="verbose", const=2,
49 help="verbose output")
Bryan Duxbury16066592011-03-22 18:06:04 +000050parser.add_option('-q', '--quiet', action="store_const",
51 dest="verbose", const=0,
52 help="minimal output")
Bryan Duxbury59d4efd2011-03-21 17:38:22 +000053parser.add_option('--proto', dest="proto", type="string",
54 help="protocol to use, one of: accel, binary, compact")
Bryan Duxbury16066592011-03-22 18:06:04 +000055parser.set_defaults(port=9090, verbose=1, proto='binary')
Bryan Duxbury59d4efd2011-03-21 17:38:22 +000056options, args = parser.parse_args()
57
Mark Sleec9676562006-09-05 17:34:52 +000058class TestHandler:
59
60 def testVoid(self):
Bryan Duxbury16066592011-03-22 18:06:04 +000061 if options.verbose > 1:
Bryan Duxbury59d4efd2011-03-21 17:38:22 +000062 print 'testVoid()'
Mark Sleec9676562006-09-05 17:34:52 +000063
64 def testString(self, str):
Bryan Duxbury16066592011-03-22 18:06:04 +000065 if options.verbose > 1:
Bryan Duxbury59d4efd2011-03-21 17:38:22 +000066 print 'testString(%s)' % str
Mark Sleec9676562006-09-05 17:34:52 +000067 return str
68
69 def testByte(self, byte):
Bryan Duxbury16066592011-03-22 18:06:04 +000070 if options.verbose > 1:
Bryan Duxbury59d4efd2011-03-21 17:38:22 +000071 print 'testByte(%d)' % byte
Mark Sleec9676562006-09-05 17:34:52 +000072 return byte
73
Mark Sleec98d0502006-09-06 02:42:25 +000074 def testI16(self, i16):
Bryan Duxbury16066592011-03-22 18:06:04 +000075 if options.verbose > 1:
Bryan Duxbury59d4efd2011-03-21 17:38:22 +000076 print 'testI16(%d)' % i16
Mark Sleec98d0502006-09-06 02:42:25 +000077 return i16
78
79 def testI32(self, i32):
Bryan Duxbury16066592011-03-22 18:06:04 +000080 if options.verbose > 1:
Bryan Duxbury59d4efd2011-03-21 17:38:22 +000081 print 'testI32(%d)' % i32
Mark Sleec98d0502006-09-06 02:42:25 +000082 return i32
83
84 def testI64(self, i64):
Bryan Duxbury16066592011-03-22 18:06:04 +000085 if options.verbose > 1:
Bryan Duxbury59d4efd2011-03-21 17:38:22 +000086 print 'testI64(%d)' % i64
Mark Sleec98d0502006-09-06 02:42:25 +000087 return i64
88
89 def testDouble(self, dub):
Bryan Duxbury16066592011-03-22 18:06:04 +000090 if options.verbose > 1:
Bryan Duxbury59d4efd2011-03-21 17:38:22 +000091 print 'testDouble(%f)' % dub
Mark Sleec98d0502006-09-06 02:42:25 +000092 return dub
93
94 def testStruct(self, thing):
Bryan Duxbury16066592011-03-22 18:06:04 +000095 if options.verbose > 1:
Bryan Duxbury59d4efd2011-03-21 17:38:22 +000096 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 +000097 return thing
98
Mark Sleec9676562006-09-05 17:34:52 +000099 def testException(self, str):
Bryan Duxbury16066592011-03-22 18:06:04 +0000100 if options.verbose > 1:
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000101 print 'testException(%s)' % str
Mark Sleec98d0502006-09-06 02:42:25 +0000102 if str == 'Xception':
103 x = Xception()
104 x.errorCode = 1001
105 x.message = str
106 raise x
David Reissbcaa2ad2008-06-10 22:55:26 +0000107 elif str == "throw_undeclared":
108 raise ValueError("foo")
Mark Sleec9676562006-09-05 17:34:52 +0000109
David Reiss6ce401d2009-03-24 20:01:58 +0000110 def testOneway(self, seconds):
Bryan Duxbury16066592011-03-22 18:06:04 +0000111 if options.verbose > 1:
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000112 print 'testOneway(%d) => sleeping...' % seconds
113 time.sleep(seconds / 3) # be quick
Bryan Duxbury16066592011-03-22 18:06:04 +0000114 if options.verbose > 1:
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000115 print 'done sleeping'
David Reissdb893b62008-02-18 02:11:48 +0000116
David Reiss74421272008-11-07 23:09:31 +0000117 def testNest(self, thing):
Bryan Duxbury16066592011-03-22 18:06:04 +0000118 if options.verbose > 1:
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000119 print 'testNest(%s)' % thing
David Reiss74421272008-11-07 23:09:31 +0000120 return thing
121
122 def testMap(self, thing):
Bryan Duxbury16066592011-03-22 18:06:04 +0000123 if options.verbose > 1:
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000124 print 'testMap(%s)' % thing
David Reiss74421272008-11-07 23:09:31 +0000125 return thing
126
127 def testSet(self, thing):
Bryan Duxbury16066592011-03-22 18:06:04 +0000128 if options.verbose > 1:
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000129 print 'testSet(%s)' % thing
David Reiss74421272008-11-07 23:09:31 +0000130 return thing
131
132 def testList(self, thing):
Bryan Duxbury16066592011-03-22 18:06:04 +0000133 if options.verbose > 1:
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000134 print 'testList(%s)' % thing
David Reiss74421272008-11-07 23:09:31 +0000135 return thing
136
137 def testEnum(self, thing):
Bryan Duxbury16066592011-03-22 18:06:04 +0000138 if options.verbose > 1:
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000139 print 'testEnum(%s)' % thing
David Reiss74421272008-11-07 23:09:31 +0000140 return thing
141
142 def testTypedef(self, thing):
Bryan Duxbury16066592011-03-22 18:06:04 +0000143 if options.verbose > 1:
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000144 print 'testTypedef(%s)' % thing
David Reiss74421272008-11-07 23:09:31 +0000145 return thing
146
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000147 def testMapMap(self, thing):
Bryan Duxbury16066592011-03-22 18:06:04 +0000148 if options.verbose > 1:
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000149 print 'testMapMap(%s)' % thing
150 return thing
151
152 def testMulti(self, arg0, arg1, arg2, arg3, arg4, arg5):
Bryan Duxbury16066592011-03-22 18:06:04 +0000153 if options.verbose > 1:
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000154 print 'testMulti(%s)' % [arg0, arg1, arg2, arg3, arg4, arg5]
155 x = Xtruct(byte_thing=arg0, i32_thing=arg1, i64_thing=arg2)
156 return x
157
Bryan Duxbury16066592011-03-22 18:06:04 +0000158# set up the protocol factory form the --proto option
159pfactory_cls = PROT_FACTORIES.get(options.proto, None)
160if pfactory_cls is None:
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000161 raise AssertionError('Unknown --proto option: %s' % options.proto)
Bryan Duxbury16066592011-03-22 18:06:04 +0000162pfactory = pfactory_cls()
163
164# get the server type (TSimpleServer, TNonblockingServer, etc...)
165if len(args) > 1:
166 raise AssertionError('Only one server type may be specified, not multiple types.')
167server_type = args[0]
168
169# Set up the handler and processor objects
Mark Sleec9676562006-09-05 17:34:52 +0000170handler = TestHandler()
Mark Slee1dd819c2006-10-26 04:56:18 +0000171processor = ThriftTest.Processor(handler)
David Reissbcaa2ad2008-06-10 22:55:26 +0000172
Bryan Duxbury16066592011-03-22 18:06:04 +0000173# Handle THttpServer as a special case
174if server_type == 'THttpServer':
175 server =THttpServer.THttpServer(processor, ('', options.port), pfactory)
176 server.serve()
177 sys.exit(0)
178
179# set up server transport and transport factory
180host = None
181if options.ssl:
182 from thrift.transport import TSSLSocket
183 transport = TSSLSocket.TSSLServerSocket(host, options.port, certfile='test_cert.pem')
David Reiss74421272008-11-07 23:09:31 +0000184else:
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000185 transport = TSocket.TServerSocket(host, options.port)
Bryan Duxbury16066592011-03-22 18:06:04 +0000186tfactory = TTransport.TBufferedTransportFactory()
David Reissf78ec2b2009-01-31 21:59:32 +0000187
Bryan Duxbury16066592011-03-22 18:06:04 +0000188# if --zlib, then wrap server transport, and use a different transport factory
189if options.zlib:
190 transport = TZlibTransport.TZlibTransport(transport) # wrap with zlib
191 tfactory = TZlibTransport.TZlibTransportFactory()
192
193# do server-specific setup here:
194if server_type == "TNonblockingServer":
195 server = TNonblockingServer.TNonblockingServer(processor, transport, inputProtocolFactory=pfactory)
196elif server_type == "TProcessPoolServer":
197 import signal
198 from thrift.server import TProcessPoolServer
199 server = TProcessPoolServer.TProcessPoolServer(processor, transport, tfactory, pfactory)
200 server.setNumWorkers(5)
201 def set_alarm():
202 def clean_shutdown(signum, frame):
203 for worker in server.workers:
204 if options.verbose > 0:
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000205 print 'Terminating worker: %s' % worker
Bryan Duxbury16066592011-03-22 18:06:04 +0000206 worker.terminate()
207 if options.verbose > 0:
Bryan Duxbury59d4efd2011-03-21 17:38:22 +0000208 print 'Requesting server to stop()'
Bryan Duxbury16066592011-03-22 18:06:04 +0000209 server.stop()
210 signal.signal(signal.SIGALRM, clean_shutdown)
211 signal.alarm(2)
212 set_alarm()
213else:
214 # look up server class dynamically to instantiate server
215 ServerClass = getattr(TServer, server_type)
216 server = ServerClass(processor, transport, tfactory, pfactory)
217# enter server main loop
Mark Slee794993d2006-09-20 01:56:10 +0000218server.serve()