PageRenderTime 105ms CodeModel.GetById 31ms RepoModel.GetById 0ms app.codeStats 0ms

/lang/py/test/test_protocol.py

https://github.com/thirumg/Avro.NET
Python | 257 lines | 238 code | 1 blank | 18 comment | 0 complexity | 3468242c8d3fca060a7e15099a6fb052 MD5 | raw file
  1. # Licensed to the Apache Software Foundation (ASF) under one
  2. # or more contributor license agreements. See the NOTICE file
  3. # distributed with this work for additional information
  4. # regarding copyright ownership. The ASF licenses this file
  5. # to you under the Apache License, Version 2.0 (the
  6. # "License"); you may not use this file except in compliance
  7. # with the License. You may obtain a copy of the License at
  8. #
  9. # http://www.apache.org/licenses/LICENSE-2.0
  10. #
  11. # Unless required by applicable law or agreed to in writing, software
  12. # distributed under the License is distributed on an "AS IS" BASIS,
  13. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. # See the License for the specific language governing permissions and
  15. # limitations under the License.
  16. """
  17. Test the protocol parsing logic.
  18. """
  19. import unittest
  20. from avro import protocol
  21. class ExampleProtocol(object):
  22. def __init__(self, protocol_string, valid, name='', comment=''):
  23. self._protocol_string = protocol_string
  24. self._valid = valid
  25. self._name = name or protocol_string # default to schema_string for name
  26. self._comment = comment
  27. # read-only properties
  28. protocol_string = property(lambda self: self._protocol_string)
  29. valid = property(lambda self: self._valid)
  30. name = property(lambda self: self._name)
  31. # read/write properties
  32. def set_comment(self, new_comment): self._comment = new_comment
  33. comment = property(lambda self: self._comment, set_comment)
  34. #
  35. # Example Protocols
  36. #
  37. EXAMPLES = [
  38. ExampleProtocol("""\
  39. {
  40. "namespace": "com.acme",
  41. "protocol": "HelloWorld",
  42. "types": [
  43. {"name": "Greeting", "type": "record", "fields": [
  44. {"name": "message", "type": "string"}]},
  45. {"name": "Curse", "type": "error", "fields": [
  46. {"name": "message", "type": "string"}]}
  47. ],
  48. "messages": {
  49. "hello": {
  50. "request": [{"name": "greeting", "type": "Greeting" }],
  51. "response": "Greeting",
  52. "errors": ["Curse"]
  53. }
  54. }
  55. }
  56. """, True),
  57. ExampleProtocol("""\
  58. {"namespace": "org.apache.avro.test",
  59. "protocol": "Simple",
  60. "types": [
  61. {"name": "Kind", "type": "enum", "symbols": ["FOO","BAR","BAZ"]},
  62. {"name": "MD5", "type": "fixed", "size": 16},
  63. {"name": "TestRecord", "type": "record",
  64. "fields": [
  65. {"name": "name", "type": "string", "order": "ignore"},
  66. {"name": "kind", "type": "Kind", "order": "descending"},
  67. {"name": "hash", "type": "MD5"}
  68. ]
  69. },
  70. {"name": "TestError", "type": "error", "fields": [
  71. {"name": "message", "type": "string"}
  72. ]
  73. }
  74. ],
  75. "messages": {
  76. "hello": {
  77. "request": [{"name": "greeting", "type": "string"}],
  78. "response": "string"
  79. },
  80. "echo": {
  81. "request": [{"name": "record", "type": "TestRecord"}],
  82. "response": "TestRecord"
  83. },
  84. "add": {
  85. "request": [{"name": "arg1", "type": "int"}, {"name": "arg2", "type": "int"}],
  86. "response": "int"
  87. },
  88. "echoBytes": {
  89. "request": [{"name": "data", "type": "bytes"}],
  90. "response": "bytes"
  91. },
  92. "error": {
  93. "request": [],
  94. "response": "null",
  95. "errors": ["TestError"]
  96. }
  97. }
  98. }
  99. """, True),
  100. ExampleProtocol("""\
  101. {"namespace": "org.apache.avro.test.namespace",
  102. "protocol": "TestNamespace",
  103. "types": [
  104. {"name": "org.apache.avro.test.util.MD5", "type": "fixed", "size": 16},
  105. {"name": "TestRecord", "type": "record",
  106. "fields": [ {"name": "hash", "type": "org.apache.avro.test.util.MD5"} ]
  107. },
  108. {"name": "TestError", "namespace": "org.apache.avro.test.errors",
  109. "type": "error", "fields": [ {"name": "message", "type": "string"} ]
  110. }
  111. ],
  112. "messages": {
  113. "echo": {
  114. "request": [{"name": "record", "type": "TestRecord"}],
  115. "response": "TestRecord"
  116. },
  117. "error": {
  118. "request": [],
  119. "response": "null",
  120. "errors": ["org.apache.avro.test.errors.TestError"]
  121. }
  122. }
  123. }
  124. """, True),
  125. ExampleProtocol("""\
  126. {"namespace": "org.apache.avro.test",
  127. "protocol": "BulkData",
  128. "types": [],
  129. "messages": {
  130. "read": {
  131. "request": [],
  132. "response": "bytes"
  133. },
  134. "write": {
  135. "request": [ {"name": "data", "type": "bytes"} ],
  136. "response": "null"
  137. }
  138. }
  139. }
  140. """, True),
  141. ]
  142. VALID_EXAMPLES = [e for e in EXAMPLES if e.valid]
  143. class TestProtocol(unittest.TestCase):
  144. def test_parse(self):
  145. print ''
  146. print 'TEST PARSE'
  147. print '=========='
  148. print ''
  149. num_correct = 0
  150. for example in EXAMPLES:
  151. try:
  152. protocol.parse(example.protocol_string)
  153. if example.valid: num_correct += 1
  154. debug_msg = "%s: PARSE SUCCESS" % example.name
  155. except:
  156. if not example.valid: num_correct += 1
  157. debug_msg = "%s: PARSE FAILURE" % example.name
  158. finally:
  159. print debug_msg
  160. fail_msg = "Parse behavior correct on %d out of %d protocols." % \
  161. (num_correct, len(EXAMPLES))
  162. self.assertEqual(num_correct, len(EXAMPLES), fail_msg)
  163. def test_valid_cast_to_string_after_parse(self):
  164. """
  165. Test that the string generated by an Avro Protocol object
  166. is, in fact, a valid Avro protocol.
  167. """
  168. print ''
  169. print 'TEST CAST TO STRING'
  170. print '==================='
  171. print ''
  172. num_correct = 0
  173. for example in VALID_EXAMPLES:
  174. protocol_data = protocol.parse(example.protocol_string)
  175. try:
  176. protocol.parse(str(protocol_data))
  177. debug_msg = "%s: STRING CAST SUCCESS" % example.name
  178. num_correct += 1
  179. except:
  180. debug_msg = "%s: STRING CAST FAILURE" % example.name
  181. finally:
  182. print debug_msg
  183. fail_msg = "Cast to string success on %d out of %d protocols" % \
  184. (num_correct, len(VALID_EXAMPLES))
  185. self.assertEqual(num_correct, len(VALID_EXAMPLES), fail_msg)
  186. def test_equivalence_after_round_trip(self):
  187. """
  188. 1. Given a string, parse it to get Avro protocol "original".
  189. 2. Serialize "original" to a string and parse that string
  190. to generate Avro protocol "round trip".
  191. 3. Ensure "original" and "round trip" protocols are equivalent.
  192. """
  193. print ''
  194. print 'TEST ROUND TRIP'
  195. print '==============='
  196. print ''
  197. num_correct = 0
  198. for example in VALID_EXAMPLES:
  199. try:
  200. original_protocol = protocol.parse(example.protocol_string)
  201. round_trip_protocol = protocol.parse(str(original_protocol))
  202. if original_protocol == round_trip_protocol:
  203. num_correct += 1
  204. debug_msg = "%s: ROUND TRIP SUCCESS" % example.name
  205. else:
  206. debug_msg = "%s: ROUND TRIP FAILURE" % example.name
  207. except:
  208. debug_msg = "%s: ROUND TRIP FAILURE" % example.name
  209. finally:
  210. print debug_msg
  211. fail_msg = "Round trip success on %d out of %d protocols" % \
  212. (num_correct, len(VALID_EXAMPLES))
  213. self.assertEqual(num_correct, len(VALID_EXAMPLES), fail_msg)
  214. if __name__ == '__main__':
  215. unittest.main()