THRIFT-1094. py: bug in TCompactProto python readMessageEnd method and updated test cases


This patch fixes a TCompactProtocol bug and expands the test cases to exercise the problem.

Patch: Will Pierce

git-svn-id: https://svn.apache.org/repos/asf/thrift/trunk@1083877 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/test/py/TestServer.py b/test/py/TestServer.py
index 581bed6..99d925a 100755
--- a/test/py/TestServer.py
+++ b/test/py/TestServer.py
@@ -18,53 +18,75 @@
 # specific language governing permissions and limitations
 # under the License.
 #
-
+from __future__ import division
 import sys, glob, time
 sys.path.insert(0, './gen-py')
 sys.path.insert(0, glob.glob('../../lib/py/build/lib.*')[0])
+from optparse import OptionParser
 
 from ThriftTest import ThriftTest
 from ThriftTest.ttypes import *
 from thrift.transport import TTransport
 from thrift.transport import TSocket
 from thrift.protocol import TBinaryProtocol
+from thrift.protocol import TCompactProtocol
 from thrift.server import TServer, TNonblockingServer, THttpServer
 
+parser = OptionParser()
+parser.set_defaults(port=9090, verbose=1, proto='binary')
+parser.add_option("--port", type="int", dest="port",
+    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('--proto',  dest="proto", type="string",
+    help="protocol to use, one of: accel, binary, compact")
+options, args = parser.parse_args()
+
 class TestHandler:
 
   def testVoid(self):
-    print 'testVoid()'
+    if options.verbose:
+      print 'testVoid()'
 
   def testString(self, str):
-    print 'testString(%s)' % str
+    if options.verbose:
+      print 'testString(%s)' % str
     return str
 
   def testByte(self, byte):
-    print 'testByte(%d)' % byte
+    if options.verbose:
+      print 'testByte(%d)' % byte
     return byte
 
   def testI16(self, i16):
-    print 'testI16(%d)' % i16
+    if options.verbose:
+      print 'testI16(%d)' % i16
     return i16
 
   def testI32(self, i32):
-    print 'testI32(%d)' % i32
+    if options.verbose:
+      print 'testI32(%d)' % i32
     return i32
 
   def testI64(self, i64):
-    print 'testI64(%d)' % i64
+    if options.verbose:
+      print 'testI64(%d)' % i64
     return i64
 
   def testDouble(self, dub):
-    print 'testDouble(%f)' % dub
+    if options.verbose:
+      print 'testDouble(%f)' % dub
     return dub
 
   def testStruct(self, thing):
-    print 'testStruct({%s, %d, %d, %d})' % (thing.string_thing, thing.byte_thing, thing.i32_thing, thing.i64_thing)
+    if options.verbose:
+      print 'testStruct({%s, %d, %d, %d})' % (thing.string_thing, thing.byte_thing, thing.i32_thing, thing.i64_thing)
     return thing
 
   def testException(self, str):
-    print 'testException(%s)' % str
+    if options.verbose:
+      print 'testException(%s)' % str
     if str == 'Xception':
       x = Xception()
       x.errorCode = 1001
@@ -74,43 +96,90 @@
       raise ValueError("foo")
 
   def testOneway(self, seconds):
-    print 'testOneway(%d) => sleeping...' % seconds
-    time.sleep(seconds)
-    print 'done sleeping'
+    if options.verbose:
+      print 'testOneway(%d) => sleeping...' % seconds
+    time.sleep(seconds / 3) # be quick
+    if options.verbose:
+      print 'done sleeping'
 
   def testNest(self, thing):
+    if options.verbose:
+      print 'testNest(%s)' % thing
     return thing
 
   def testMap(self, thing):
+    if options.verbose:
+      print 'testMap(%s)' % thing
     return thing
 
   def testSet(self, thing):
+    if options.verbose:
+      print 'testSet(%s)' % thing
     return thing
 
   def testList(self, thing):
+    if options.verbose:
+      print 'testList(%s)' % thing
     return thing
 
   def testEnum(self, thing):
+    if options.verbose:
+      print 'testEnum(%s)' % thing
     return thing
 
   def testTypedef(self, thing):
+    if options.verbose:
+      print 'testTypedef(%s)' % thing
     return thing
 
-pfactory = TBinaryProtocol.TBinaryProtocolFactory()
+  def testMapMap(self, thing):
+    if options.verbose:
+      print 'testMapMap(%s)' % thing
+    return thing
+
+  def testMulti(self, arg0, arg1, arg2, arg3, arg4, arg5):
+    if options.verbose:
+      print 'testMulti(%s)' % [arg0, arg1, arg2, arg3, arg4, arg5]
+    x = Xtruct(byte_thing=arg0, i32_thing=arg1, i64_thing=arg2)
+    return x
+
+if options.proto == 'binary':
+  pfactory = TBinaryProtocol.TBinaryProtocolFactory()
+elif options.proto == 'accel':
+  pfactory = TBinaryProtocol.TBinaryProtocolAcceleratedFactory()
+elif options.proto == 'compact':
+  pfactory = TCompactProtocol.TCompactProtocolFactory()
+else:
+  raise AssertionError('Unknown --proto option: %s' % options.proto)
 handler = TestHandler()
 processor = ThriftTest.Processor(handler)
 
-if sys.argv[1] == "THttpServer":
-  server = THttpServer.THttpServer(processor, ('', 9090), pfactory)
+if args[0] == "THttpServer":
+  server = THttpServer.THttpServer(processor, ('', options.port), pfactory)
 else:
   host = None
-  transport = TSocket.TServerSocket(host, 9090)
+  transport = TSocket.TServerSocket(host, options.port)
   tfactory = TTransport.TBufferedTransportFactory()
 
-  if sys.argv[1] == "TNonblockingServer":
-    server = TNonblockingServer.TNonblockingServer(processor, transport)
+  if args[0] == "TNonblockingServer":
+    server = TNonblockingServer.TNonblockingServer(processor, transport, inputProtocolFactory=pfactory)
+  elif args[0] == "TProcessPoolServer":
+    import signal
+    def set_alarm():
+      def clean_shutdown(signum, frame):
+        for worker in server.workers:
+          print 'Terminating worker: %s' % worker
+          worker.terminate()
+        print 'Requesting server to stop()'
+        server.stop()
+      signal.signal(signal.SIGALRM, clean_shutdown)
+      signal.alarm(2)
+    from thrift.server import TProcessPoolServer
+    server = TProcessPoolServer.TProcessPoolServer(processor, transport, tfactory, pfactory)
+    server.setNumWorkers(5)
+    set_alarm()
   else:
-    ServerClass = getattr(TServer, sys.argv[1])
+    ServerClass = getattr(TServer, args[0])
     server = ServerClass(processor, transport, tfactory, pfactory)
 
 server.serve()