_reflection_servicer_test.py 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. # Copyright 2016, Google Inc.
  2. # All rights reserved.
  3. #
  4. # Redistribution and use in source and binary forms, with or without
  5. # modification, are permitted provided that the following conditions are
  6. # met:
  7. #
  8. # * Redistributions of source code must retain the above copyright
  9. # notice, this list of conditions and the following disclaimer.
  10. # * Redistributions in binary form must reproduce the above
  11. # copyright notice, this list of conditions and the following disclaimer
  12. # in the documentation and/or other materials provided with the
  13. # distribution.
  14. # * Neither the name of Google Inc. nor the names of its
  15. # contributors may be used to endorse or promote products derived from
  16. # this software without specific prior written permission.
  17. #
  18. # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  19. # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  20. # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  21. # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  22. # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  23. # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  24. # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  25. # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  26. # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27. # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  28. # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. """Tests of grpc.reflection.v1alpha.reflection."""
  30. import unittest
  31. import grpc
  32. from grpc.framework.foundation import logging_pool
  33. from grpc.reflection.v1alpha import reflection
  34. from grpc.reflection.v1alpha import reflection_pb2
  35. from google.protobuf import descriptor_pool
  36. from google.protobuf import descriptor_pb2
  37. from src.proto.grpc.testing.proto2 import empty2_extensions_pb2
  38. from src.proto.grpc.testing import empty_pb2
  39. from tests.unit.framework.common import test_constants
  40. _EMPTY_PROTO_FILE_NAME = 'src/proto/grpc/testing/empty.proto'
  41. _EMPTY_PROTO_SYMBOL_NAME = 'grpc.testing.Empty'
  42. _SERVICE_NAMES = (
  43. 'Angstrom', 'Bohr', 'Curie', 'Dyson', 'Einstein', 'Feynman', 'Galilei')
  44. def _file_descriptor_to_proto(descriptor):
  45. proto = descriptor_pb2.FileDescriptorProto()
  46. descriptor.CopyToProto(proto)
  47. return proto.SerializeToString()
  48. class ReflectionServicerTest(unittest.TestCase):
  49. def setUp(self):
  50. servicer = reflection.ReflectionServicer(service_names=_SERVICE_NAMES)
  51. server_pool = logging_pool.pool(test_constants.THREAD_CONCURRENCY)
  52. self._server = grpc.server(server_pool)
  53. port = self._server.add_insecure_port('[::]:0')
  54. reflection_pb2.add_ServerReflectionServicer_to_server(servicer, self._server)
  55. self._server.start()
  56. channel = grpc.insecure_channel('localhost:%d' % port)
  57. self._stub = reflection_pb2.ServerReflectionStub(channel)
  58. def testFileByName(self):
  59. requests = (
  60. reflection_pb2.ServerReflectionRequest(
  61. file_by_filename=_EMPTY_PROTO_FILE_NAME
  62. ),
  63. reflection_pb2.ServerReflectionRequest(
  64. file_by_filename='i-donut-exist'
  65. ),
  66. )
  67. responses = tuple(self._stub.ServerReflectionInfo(requests))
  68. expected_responses = (
  69. reflection_pb2.ServerReflectionResponse(
  70. valid_host='',
  71. file_descriptor_response=reflection_pb2.FileDescriptorResponse(
  72. file_descriptor_proto=(
  73. _file_descriptor_to_proto(empty_pb2.DESCRIPTOR),
  74. )
  75. )
  76. ),
  77. reflection_pb2.ServerReflectionResponse(
  78. valid_host='',
  79. error_response=reflection_pb2.ErrorResponse(
  80. error_code=grpc.StatusCode.NOT_FOUND.value[0],
  81. error_message=grpc.StatusCode.NOT_FOUND.value[1].encode(),
  82. )
  83. ),
  84. )
  85. self.assertEqual(expected_responses, responses)
  86. def testFileBySymbol(self):
  87. requests = (
  88. reflection_pb2.ServerReflectionRequest(
  89. file_containing_symbol=_EMPTY_PROTO_SYMBOL_NAME
  90. ),
  91. reflection_pb2.ServerReflectionRequest(
  92. file_containing_symbol='i.donut.exist.co.uk.org.net.me.name.foo'
  93. ),
  94. )
  95. responses = tuple(self._stub.ServerReflectionInfo(requests))
  96. expected_responses = (
  97. reflection_pb2.ServerReflectionResponse(
  98. valid_host='',
  99. file_descriptor_response=reflection_pb2.FileDescriptorResponse(
  100. file_descriptor_proto=(
  101. _file_descriptor_to_proto(empty_pb2.DESCRIPTOR),
  102. )
  103. )
  104. ),
  105. reflection_pb2.ServerReflectionResponse(
  106. valid_host='',
  107. error_response=reflection_pb2.ErrorResponse(
  108. error_code=grpc.StatusCode.NOT_FOUND.value[0],
  109. error_message=grpc.StatusCode.NOT_FOUND.value[1].encode(),
  110. )
  111. ),
  112. )
  113. self.assertEqual(expected_responses, responses)
  114. @unittest.skip('TODO(atash): implement file-containing-extension reflection '
  115. '(see https://github.com/google/protobuf/issues/2248)')
  116. def testFileContainingExtension(self):
  117. requests = (
  118. reflection_pb2.ServerReflectionRequest(
  119. file_containing_extension=reflection_pb2.ExtensionRequest(
  120. containing_type='grpc.testing.proto2.Empty',
  121. extension_number=125,
  122. ),
  123. ),
  124. reflection_pb2.ServerReflectionRequest(
  125. file_containing_extension=reflection_pb2.ExtensionRequest(
  126. containing_type='i.donut.exist.co.uk.org.net.me.name.foo',
  127. extension_number=55,
  128. ),
  129. ),
  130. )
  131. responses = tuple(self._stub.ServerReflectionInfo(requests))
  132. expected_responses = (
  133. reflection_pb2.ServerReflectionResponse(
  134. valid_host='',
  135. file_descriptor_response=reflection_pb2.FileDescriptorResponse(
  136. file_descriptor_proto=(
  137. _file_descriptor_to_proto(empty_extensions_pb2.DESCRIPTOR),
  138. )
  139. )
  140. ),
  141. reflection_pb2.ServerReflectionResponse(
  142. valid_host='',
  143. error_response=reflection_pb2.ErrorResponse(
  144. error_code=grpc.StatusCode.NOT_FOUND.value[0],
  145. error_message=grpc.StatusCode.NOT_FOUND.value[1].encode(),
  146. )
  147. ),
  148. )
  149. self.assertEqual(expected_responses, responses)
  150. def testListServices(self):
  151. requests = (
  152. reflection_pb2.ServerReflectionRequest(
  153. list_services='',
  154. ),
  155. )
  156. responses = tuple(self._stub.ServerReflectionInfo(requests))
  157. expected_responses = (
  158. reflection_pb2.ServerReflectionResponse(
  159. valid_host='',
  160. list_services_response=reflection_pb2.ListServiceResponse(
  161. service=tuple(
  162. reflection_pb2.ServiceResponse(name=name)
  163. for name in _SERVICE_NAMES
  164. )
  165. )
  166. ),
  167. )
  168. self.assertEqual(expected_responses, responses)
  169. if __name__ == '__main__':
  170. unittest.main(verbosity=2)