summaryrefslogtreecommitdiff
path: root/test/py
diff options
context:
space:
mode:
authorNobuaki Sukegawa <nsuke@apache.org>2015-11-17 11:01:17 +0900
committerRoger Meier <roger@apache.org>2015-11-28 00:08:07 +0100
commite841b3dac619a5e5d3523d059d48db1a12e41360 (patch)
tree183832cb3b7b9c6cdf10c9f1183a47f8410905ce /test/py
parentb9641e0949f5de5a3c8079758fdd638889614143 (diff)
downloadthrift-e841b3dac619a5e5d3523d059d48db1a12e41360.tar.gz
THRIFT-162 Thrift structures are unhashable, preventing them from being used as set elements
Client: Python Patch: David Reiss, Nobuaki Sukegawa This closes #714
Diffstat (limited to 'test/py')
-rwxr-xr-xtest/py/RunClientServer.py1
-rwxr-xr-xtest/py/TestFrozen.py116
2 files changed, 117 insertions, 0 deletions
diff --git a/test/py/RunClientServer.py b/test/py/RunClientServer.py
index fa2a26411..f084a41ed 100755
--- a/test/py/RunClientServer.py
+++ b/test/py/RunClientServer.py
@@ -37,6 +37,7 @@ DEFAULT_LIBDIR_GLOB = os.path.join(ROOT_DIR, 'lib', 'py', 'build', 'lib.*')
DEFAULT_LIBDIR_PY3 = os.path.join(ROOT_DIR, 'lib', 'py', 'build', 'lib')
SCRIPTS = [
+ 'TestFrozen.py',
'TSimpleJSONProtocolTest.py',
'SerializationTest.py',
'TestEof.py',
diff --git a/test/py/TestFrozen.py b/test/py/TestFrozen.py
new file mode 100755
index 000000000..76750ad88
--- /dev/null
+++ b/test/py/TestFrozen.py
@@ -0,0 +1,116 @@
+#!/usr/bin/env python
+
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+from DebugProtoTest.ttypes import CompactProtoTestStruct, Empty, Wrapper
+from thrift.Thrift import TFrozenDict
+from thrift.transport import TTransport
+from thrift.protocol import TBinaryProtocol
+import collections
+import unittest
+
+
+class TestFrozenBase(unittest.TestCase):
+ def _roundtrip(self, src, dst):
+ otrans = TTransport.TMemoryBuffer()
+ optoro = self.protocol(otrans)
+ src.write(optoro)
+ itrans = TTransport.TMemoryBuffer(otrans.getvalue())
+ iproto = self.protocol(itrans)
+ return dst.read(iproto) or dst
+
+ def test_dict_is_hashable_only_after_frozen(self):
+ d0 = {}
+ self.assertFalse(isinstance(d0, collections.Hashable))
+ d1 = TFrozenDict(d0)
+ self.assertTrue(isinstance(d1, collections.Hashable))
+
+ def test_struct_with_collection_fields(self):
+ pass
+
+ def test_set(self):
+ """Test that annotated set field can be serialized and deserialized"""
+ x = CompactProtoTestStruct(set_byte_map={
+ frozenset([42, 100, -100]): 99,
+ frozenset([0]): 100,
+ frozenset([]): 0,
+ })
+ x2 = self._roundtrip(x, CompactProtoTestStruct())
+ self.assertEqual(x2.set_byte_map[frozenset([42, 100, -100])], 99)
+ self.assertEqual(x2.set_byte_map[frozenset([0])], 100)
+ self.assertEqual(x2.set_byte_map[frozenset([])], 0)
+
+ def test_map(self):
+ """Test that annotated map field can be serialized and deserialized"""
+ x = CompactProtoTestStruct(map_byte_map={
+ TFrozenDict({42: 42, 100: -100}): 99,
+ TFrozenDict({0: 0}): 100,
+ TFrozenDict({}): 0,
+ })
+ x2 = self._roundtrip(x, CompactProtoTestStruct())
+ self.assertEqual(x2.map_byte_map[TFrozenDict({42: 42, 100: -100})], 99)
+ self.assertEqual(x2.map_byte_map[TFrozenDict({0: 0})], 100)
+ self.assertEqual(x2.map_byte_map[TFrozenDict({})], 0)
+
+ def test_list(self):
+ """Test that annotated list field can be serialized and deserialized"""
+ x = CompactProtoTestStruct(list_byte_map={
+ (42, 100, -100): 99,
+ (0,): 100,
+ (): 0,
+ })
+ x2 = self._roundtrip(x, CompactProtoTestStruct())
+ self.assertEqual(x2.list_byte_map[(42, 100, -100)], 99)
+ self.assertEqual(x2.list_byte_map[(0,)], 100)
+ self.assertEqual(x2.list_byte_map[()], 0)
+
+ def test_empty_struct(self):
+ """Test that annotated empty struct can be serialized and deserialized"""
+ x = CompactProtoTestStruct(empty_struct_field=Empty())
+ x2 = self._roundtrip(x, CompactProtoTestStruct())
+ self.assertEqual(x2.empty_struct_field, Empty())
+
+ def test_struct(self):
+ """Test that annotated struct can be serialized and deserialized"""
+ x = Wrapper(foo=Empty())
+ self.assertEqual(x.foo, Empty())
+ x2 = self._roundtrip(x, Wrapper)
+ self.assertEqual(x2.foo, Empty())
+
+
+class TestFrozen(TestFrozenBase):
+ def protocol(self, trans):
+ return TBinaryProtocol.TBinaryProtocolFactory().getProtocol(trans)
+
+
+class TestFrozenAccelerated(TestFrozenBase):
+ def protocol(self, trans):
+ return TBinaryProtocol.TBinaryProtocolAcceleratedFactory().getProtocol(trans)
+
+
+def suite():
+ suite = unittest.TestSuite()
+ loader = unittest.TestLoader()
+ suite.addTest(loader.loadTestsFromTestCase(TestFrozen))
+ suite.addTest(loader.loadTestsFromTestCase(TestFrozenAccelerated))
+ return suite
+
+if __name__ == "__main__":
+ unittest.main(defaultTest="suite", testRunner=unittest.TextTestRunner(verbosity=2))