diff options
author | Nobuaki Sukegawa <nsuke@apache.org> | 2015-11-17 11:01:17 +0900 |
---|---|---|
committer | Roger Meier <roger@apache.org> | 2015-11-28 00:08:07 +0100 |
commit | e841b3dac619a5e5d3523d059d48db1a12e41360 (patch) | |
tree | 183832cb3b7b9c6cdf10c9f1183a47f8410905ce /test/py | |
parent | b9641e0949f5de5a3c8079758fdd638889614143 (diff) | |
download | thrift-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-x | test/py/RunClientServer.py | 1 | ||||
-rwxr-xr-x | test/py/TestFrozen.py | 116 |
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)) |