Thrift: Python test improvements.

Summary:
- Add a serialization test for forwards/backwards compatibility.
- Hook the Python tests up to "make check".
- Miscellaneous changes to the Python tests.

Reviewed By: mcslee

Test Plan: Ran the test.


git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@665480 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/cleanup.sh b/cleanup.sh
index fe0d6ed..0f2cc70 100755
--- a/cleanup.sh
+++ b/cleanup.sh
@@ -35,4 +35,5 @@
 lib/cpp/Makefile.in \
 lib/py/Makefile.in \
 lib/csharp/Makefile.in \
-test/Makefile.in
+test/Makefile.in \
+test/py/Makefile.in
diff --git a/configure.ac b/configure.ac
index 94a0f10..fd29a0f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -121,6 +121,7 @@
   lib/py/Makefile
   if/Makefile
   test/Makefile
+  test/py/Makefile
 ])
 
 AC_OUTPUT
diff --git a/test/Makefile.am b/test/Makefile.am
index 1a95001..5fb3941 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -1,3 +1,5 @@
+SUBDIRS = py
+
 check_PROGRAMS = \
 	DebugProtoTest \
 	OptionalRequiredTest \
diff --git a/test/ThriftTest.thrift b/test/ThriftTest.thrift
index 8c91cb7..9056465 100644
--- a/test/ThriftTest.thrift
+++ b/test/ThriftTest.thrift
@@ -96,3 +96,24 @@
 {
   void blahBlah()
 }
+
+struct VersioningTestV1 {
+       1: i32 begin_in_both,
+       12: i32 end_in_both
+}
+
+struct VersioningTestV2 {
+       1: i32 begin_in_both,
+
+       2: i32 newint,
+       3: byte newbyte,
+       4: i16 newshort,
+       5: i64 newlong,
+       6: double newdouble
+       7: Bonk newstruct,
+       8: list<i32> newlist,
+       9: set<i32> newset,
+       10: map<i32, i32> newmap,
+       11: string newstring,
+       12: i32 end_in_both
+}
\ No newline at end of file
diff --git a/test/py/Makefile b/test/py/Makefile
deleted file mode 100644
index 2049663..0000000
--- a/test/py/Makefile
+++ /dev/null
@@ -1,18 +0,0 @@
-# Makefile for Thrift test project.
-#
-# Author:
-#   Mark Slee <mcslee@facebook.com>
-
-# Default target is everything
-target: all
-
-# Tools
-THRIFT = ../../compiler/cpp/thrift
-
-all: stubs
-
-stubs: ../ThriftTest.thrift
-	$(THRIFT) --py ../ThriftTest.thrift
-
-clean:
-	rm -fr gen-py
diff --git a/test/py/Makefile.am b/test/py/Makefile.am
new file mode 100644
index 0000000..0d159a2
--- /dev/null
+++ b/test/py/Makefile.am
@@ -0,0 +1,27 @@
+THRIFT = $(top_srcdir)/compiler/cpp/thrift
+
+py_unit_tests =                                 \
+        SerializationTest.py                    \
+        TestEof.py                              \
+        RunClientServer.py
+
+thrift_gen =                                    \
+        gen-py/ThriftTest/__init__.py
+
+helper_scripts=                                 \
+        TestClient.py                           \
+        TestServer.py
+
+check_SCRIPTS=                                  \
+        $(thrift_gen)                           \
+        $(py_unit_tests)                        \
+        $(helper_scripts)
+
+TESTS= $(py_unit_tests)
+
+
+gen-py/ThriftTest/__init__.py: ../ThriftTest.thrift
+	$(THRIFT) -py $<
+
+clean-local:
+	-rm -rf gen-py
diff --git a/test/py/RunClientServer.py b/test/py/RunClientServer.py
old mode 100644
new mode 100755
diff --git a/test/py/SerializationTest.py b/test/py/SerializationTest.py
new file mode 100755
index 0000000..56bccbf
--- /dev/null
+++ b/test/py/SerializationTest.py
@@ -0,0 +1,76 @@
+#!/usr/bin/env python
+
+import sys, glob
+sys.path.insert(0, './gen-py')
+sys.path.insert(0, glob.glob('../../lib/py/build/lib.*')[0])
+
+from ThriftTest.ttypes import *
+from thrift.transport import TTransport
+from thrift.transport import TSocket
+from thrift.protocol import TBinaryProtocol
+import unittest
+import time
+
+class AbstractTest(unittest.TestCase):
+
+  def setUp(self):
+      self.v1obj = VersioningTestV1(d=dict(
+          begin_in_both=12345,
+          end_in_both=54321,
+          ))
+
+      self.v2obj = VersioningTestV2(d=dict(
+          begin_in_both=12345,
+          newint=1,
+          newbyte=2,
+          newshort=3,
+          newlong=4,
+          newdouble=5.0,
+          newstruct=Bonk(d=dict(message="Hello!", type=123)),
+          newlist=[7,8,9],
+          newset=[42,1,8],
+          newmap={1:2,2:3},
+          newstring="Hola!",
+          end_in_both=54321,
+          ))
+
+  def _serialize(self, obj):
+      trans = TTransport.TMemoryBuffer()
+      prot = self.protocol_factory.getProtocol(trans)
+      obj.write(prot)
+      return trans.getvalue()
+
+  def _deserialize(self, objtype, data):
+      prot = self.protocol_factory.getProtocol(TTransport.TMemoryBuffer(data))
+      ret = objtype()
+      ret.read(prot)
+      return ret
+
+  def testForwards(self):
+      obj = self._deserialize(VersioningTestV2, self._serialize(self.v1obj))
+      assert obj.begin_in_both == self.v1obj.begin_in_both
+      assert obj.end_in_both == self.v1obj.end_in_both
+
+  def testBackwards(self):
+      obj = self._deserialize(VersioningTestV1, self._serialize(self.v2obj))
+      assert obj.begin_in_both == self.v2obj.begin_in_both
+      assert obj.end_in_both == self.v2obj.end_in_both
+
+
+class NormalBinaryTest(AbstractTest):
+  protocol_factory = TBinaryProtocol.TBinaryProtocolFactory()
+
+class AcceleratedBinaryTest(AbstractTest):
+  protocol_factory = TBinaryProtocol.TBinaryProtocolAcceleratedFactory()
+
+
+def suite():
+  suite = unittest.TestSuite()
+  loader = unittest.TestLoader()
+
+  suite.addTest(loader.loadTestsFromTestCase(NormalBinaryTest))
+  suite.addTest(loader.loadTestsFromTestCase(AcceleratedBinaryTest))
+  return suite
+
+if __name__ == "__main__":
+  unittest.main(defaultTest="suite", testRunner=unittest.TextTestRunner(verbosity=2))
diff --git a/test/py/TestClient.py b/test/py/TestClient.py
index 7e58dfe..ab2cba8 100755
--- a/test/py/TestClient.py
+++ b/test/py/TestClient.py
@@ -92,11 +92,13 @@
 class AcceleratedBinaryTest(AbstractTest):
   protocol_factory = TBinaryProtocol.TBinaryProtocolAcceleratedFactory()
 
-suite = unittest.TestSuite()
-loader = unittest.TestLoader()
+def suite():
+  suite = unittest.TestSuite()
+  loader = unittest.TestLoader()
 
-suite.addTest(loader.loadTestsFromTestCase(NormalBinaryTest))
-suite.addTest(loader.loadTestsFromTestCase(AcceleratedBinaryTest))
+  suite.addTest(loader.loadTestsFromTestCase(NormalBinaryTest))
+  suite.addTest(loader.loadTestsFromTestCase(AcceleratedBinaryTest))
+  return suite
 
-testRunner = unittest.TextTestRunner(verbosity=2)
-testRunner.run(suite)
+if __name__ == "__main__":
+  unittest.main(defaultTest="suite", testRunner=unittest.TextTestRunner(verbosity=2))
diff --git a/test/py/TestEof.py b/test/py/TestEof.py
old mode 100644
new mode 100755
index a23a441..7dd964f
--- a/test/py/TestEof.py
+++ b/test/py/TestEof.py
@@ -92,10 +92,11 @@
     self.eofTestHelper(TBinaryProtocol.TBinaryProtocolAcceleratedFactory())
     self.eofTestHelperStress(TBinaryProtocol.TBinaryProtocolAcceleratedFactory())
 
-suite = unittest.TestSuite()
-loader = unittest.TestLoader()
+def suite():
+  suite = unittest.TestSuite()
+  loader = unittest.TestLoader()
+  suite.addTest(loader.loadTestsFromTestCase(TestEof))
+  return suite
 
-suite.addTest(loader.loadTestsFromTestCase(TestEof))
-
-testRunner = unittest.TextTestRunner(verbosity=2)
-testRunner.run(suite)
+if __name__ == "__main__":
+  unittest.main(defaultTest="suite", testRunner=unittest.TextTestRunner(verbosity=2))