THRIFT-67. python: Add TNonblockingServer

This TNonblockingServer is very similar to the C++ implementation.
It assumes the framed transport, but it uses select instead of libevent.


git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@712306 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/test/py/RunClientServer.py b/test/py/RunClientServer.py
index cbff372..48eadb6 100755
--- a/test/py/RunClientServer.py
+++ b/test/py/RunClientServer.py
@@ -9,12 +9,16 @@
 def relfile(fname):
     return os.path.join(os.path.dirname(__file__), fname)
 
+FRAMED = ["TNonblockingServer"]
+
 def runTest(server_class):
     print "Testing ", server_class
     serverproc = subprocess.Popen([sys.executable, relfile("TestServer.py"), server_class])
     try:
-
-        ret = subprocess.call([sys.executable, relfile("TestClient.py")])
+        argv = [sys.executable, relfile("TestClient.py")]
+        if server_class in FRAMED:
+            argv.append('--framed')
+        ret = subprocess.call(argv)
         if ret != 0:
             raise Exception("subprocess failed")
     finally:
@@ -25,4 +29,4 @@
     time.sleep(5)
 
 map(runTest, ["TForkingServer", "TThreadPoolServer",
-              "TThreadedServer", "TSimpleServer"])
+              "TThreadedServer", "TSimpleServer", "TNonblockingServer"])
diff --git a/test/py/TestClient.py b/test/py/TestClient.py
index fb0133a..78dc80a 100755
--- a/test/py/TestClient.py
+++ b/test/py/TestClient.py
@@ -15,24 +15,29 @@
 
 
 parser = OptionParser()
+parser.set_defaults(framed=False, verbose=1, host='localhost', port=9090)
+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("--framed", action="store_true", dest="framed",
+    help="use framed 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("--port", type="int", dest="port", default=9090)
-parser.add_option("--host", type="string", dest="host", default='localhost')
-parser.add_option("--framed-input", action="store_true", dest="framed_input")
-parser.add_option("--framed-output", action="store_false", dest="framed_output")
-
-(options, args) = parser.parse_args()
+options, args = parser.parse_args()
 
 class AbstractTest(unittest.TestCase):
-
   def setUp(self):
-    global options
-
     socket = TSocket.TSocket(options.host, options.port)
 
     # Frame or buffer depending upon args
-    if options.framed_input or options.framed_output:
-      self.transport = TTransport.TFramedTransport(socket, options.framed_input, options.framed_output)
+    if options.framed:
+      self.transport = TTransport.TFramedTransport(socket)
     else:
       self.transport = TTransport.TBufferedTransport(socket)
 
@@ -113,5 +118,13 @@
   suite.addTest(loader.loadTestsFromTestCase(AcceleratedBinaryTest))
   return suite
 
+class OwnArgsTestProgram(unittest.TestProgram):
+    def parseArgs(self, argv):
+        if args:
+            self.testNames = args
+        else:
+            self.testNames = (self.defaultTest,)
+        self.createTests()
+
 if __name__ == "__main__":
-  unittest.main(defaultTest="suite", testRunner=unittest.TextTestRunner(verbosity=2))
+  OwnArgsTestProgram(defaultTest="suite", testRunner=unittest.TextTestRunner(verbosity=2))
diff --git a/test/py/TestServer.py b/test/py/TestServer.py
index 0247bc2..a7bf6d0 100755
--- a/test/py/TestServer.py
+++ b/test/py/TestServer.py
@@ -9,7 +9,7 @@
 from thrift.transport import TTransport
 from thrift.transport import TSocket
 from thrift.protocol import TBinaryProtocol
-from thrift.server import TServer
+from thrift.server import TServer, TNonblockingServer
 
 class TestHandler:
 
@@ -59,13 +59,33 @@
     time.sleep(seconds)
     print 'done sleeping'
 
+  def testNest(self, thing):
+    return thing
+
+  def testMap(self, thing):
+    return thing
+
+  def testSet(self, thing):
+    return thing
+
+  def testList(self, thing):
+    return thing
+
+  def testEnum(self, thing):
+    return thing
+
+  def testTypedef(self, thing):
+    return thing
+
 handler = TestHandler()
 processor = ThriftTest.Processor(handler)
 transport = TSocket.TServerSocket(9090)
 tfactory = TTransport.TBufferedTransportFactory()
 pfactory = TBinaryProtocol.TBinaryProtocolFactory()
 
-ServerClass = getattr(TServer, sys.argv[1])
-
-server = ServerClass(processor, transport, tfactory, pfactory)
+if sys.argv[1] == "TNonblockingServer":
+  server = TNonblockingServer.TNonblockingServer(processor, transport)
+else:
+  ServerClass = getattr(TServer, sys.argv[1])
+  server = ServerClass(processor, transport, tfactory, pfactory)
 server.serve()