1# Copyright 2016 gRPC authors. 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14"""Tests of grpc_reflection.v1alpha.reflection.""" 15 16import logging 17import unittest 18 19import grpc 20from google.protobuf import descriptor_pb2 21from grpc.experimental import aio 22 23from grpc_reflection.v1alpha import (reflection, reflection_pb2, 24 reflection_pb2_grpc) 25from src.proto.grpc.testing import empty_pb2 26from src.proto.grpc.testing.proto2 import empty2_extensions_pb2 27from tests_aio.unit._test_base import AioTestBase 28 29_EMPTY_PROTO_FILE_NAME = 'src/proto/grpc/testing/empty.proto' 30_EMPTY_PROTO_SYMBOL_NAME = 'grpc.testing.Empty' 31_SERVICE_NAMES = ('Angstrom', 'Bohr', 'Curie', 'Dyson', 'Einstein', 'Feynman', 32 'Galilei') 33_EMPTY_EXTENSIONS_SYMBOL_NAME = 'grpc.testing.proto2.EmptyWithExtensions' 34_EMPTY_EXTENSIONS_NUMBERS = ( 35 124, 36 125, 37 126, 38 127, 39 128, 40) 41 42 43def _file_descriptor_to_proto(descriptor): 44 proto = descriptor_pb2.FileDescriptorProto() 45 descriptor.CopyToProto(proto) 46 return proto.SerializeToString() 47 48 49class ReflectionServicerTest(AioTestBase): 50 51 async def setUp(self): 52 self._server = aio.server() 53 reflection.enable_server_reflection(_SERVICE_NAMES, self._server) 54 port = self._server.add_insecure_port('[::]:0') 55 await self._server.start() 56 57 self._channel = aio.insecure_channel('localhost:%d' % port) 58 self._stub = reflection_pb2_grpc.ServerReflectionStub(self._channel) 59 60 async def tearDown(self): 61 await self._server.stop(None) 62 await self._channel.close() 63 64 async def test_file_by_name(self): 65 requests = ( 66 reflection_pb2.ServerReflectionRequest( 67 file_by_filename=_EMPTY_PROTO_FILE_NAME), 68 reflection_pb2.ServerReflectionRequest( 69 file_by_filename='i-donut-exist'), 70 ) 71 responses = [] 72 async for response in self._stub.ServerReflectionInfo(iter(requests)): 73 responses.append(response) 74 expected_responses = ( 75 reflection_pb2.ServerReflectionResponse( 76 valid_host='', 77 file_descriptor_response=reflection_pb2.FileDescriptorResponse( 78 file_descriptor_proto=( 79 _file_descriptor_to_proto(empty_pb2.DESCRIPTOR),))), 80 reflection_pb2.ServerReflectionResponse( 81 valid_host='', 82 error_response=reflection_pb2.ErrorResponse( 83 error_code=grpc.StatusCode.NOT_FOUND.value[0], 84 error_message=grpc.StatusCode.NOT_FOUND.value[1].encode(), 85 )), 86 ) 87 self.assertSequenceEqual(expected_responses, responses) 88 89 async def test_file_by_symbol(self): 90 requests = ( 91 reflection_pb2.ServerReflectionRequest( 92 file_containing_symbol=_EMPTY_PROTO_SYMBOL_NAME), 93 reflection_pb2.ServerReflectionRequest( 94 file_containing_symbol='i.donut.exist.co.uk.org.net.me.name.foo' 95 ), 96 ) 97 responses = [] 98 async for response in self._stub.ServerReflectionInfo(iter(requests)): 99 responses.append(response) 100 expected_responses = ( 101 reflection_pb2.ServerReflectionResponse( 102 valid_host='', 103 file_descriptor_response=reflection_pb2.FileDescriptorResponse( 104 file_descriptor_proto=( 105 _file_descriptor_to_proto(empty_pb2.DESCRIPTOR),))), 106 reflection_pb2.ServerReflectionResponse( 107 valid_host='', 108 error_response=reflection_pb2.ErrorResponse( 109 error_code=grpc.StatusCode.NOT_FOUND.value[0], 110 error_message=grpc.StatusCode.NOT_FOUND.value[1].encode(), 111 )), 112 ) 113 self.assertSequenceEqual(expected_responses, responses) 114 115 async def test_file_containing_extension(self): 116 requests = ( 117 reflection_pb2.ServerReflectionRequest( 118 file_containing_extension=reflection_pb2.ExtensionRequest( 119 containing_type=_EMPTY_EXTENSIONS_SYMBOL_NAME, 120 extension_number=125, 121 ),), 122 reflection_pb2.ServerReflectionRequest( 123 file_containing_extension=reflection_pb2.ExtensionRequest( 124 containing_type='i.donut.exist.co.uk.org.net.me.name.foo', 125 extension_number=55, 126 ),), 127 ) 128 responses = [] 129 async for response in self._stub.ServerReflectionInfo(iter(requests)): 130 responses.append(response) 131 expected_responses = ( 132 reflection_pb2.ServerReflectionResponse( 133 valid_host='', 134 file_descriptor_response=reflection_pb2.FileDescriptorResponse( 135 file_descriptor_proto=(_file_descriptor_to_proto( 136 empty2_extensions_pb2.DESCRIPTOR),))), 137 reflection_pb2.ServerReflectionResponse( 138 valid_host='', 139 error_response=reflection_pb2.ErrorResponse( 140 error_code=grpc.StatusCode.NOT_FOUND.value[0], 141 error_message=grpc.StatusCode.NOT_FOUND.value[1].encode(), 142 )), 143 ) 144 self.assertSequenceEqual(expected_responses, responses) 145 146 async def test_extension_numbers_of_type(self): 147 requests = ( 148 reflection_pb2.ServerReflectionRequest( 149 all_extension_numbers_of_type=_EMPTY_EXTENSIONS_SYMBOL_NAME), 150 reflection_pb2.ServerReflectionRequest( 151 all_extension_numbers_of_type='i.donut.exist.co.uk.net.name.foo' 152 ), 153 ) 154 responses = [] 155 async for response in self._stub.ServerReflectionInfo(iter(requests)): 156 responses.append(response) 157 expected_responses = ( 158 reflection_pb2.ServerReflectionResponse( 159 valid_host='', 160 all_extension_numbers_response=reflection_pb2. 161 ExtensionNumberResponse( 162 base_type_name=_EMPTY_EXTENSIONS_SYMBOL_NAME, 163 extension_number=_EMPTY_EXTENSIONS_NUMBERS)), 164 reflection_pb2.ServerReflectionResponse( 165 valid_host='', 166 error_response=reflection_pb2.ErrorResponse( 167 error_code=grpc.StatusCode.NOT_FOUND.value[0], 168 error_message=grpc.StatusCode.NOT_FOUND.value[1].encode(), 169 )), 170 ) 171 self.assertSequenceEqual(expected_responses, responses) 172 173 async def test_list_services(self): 174 requests = (reflection_pb2.ServerReflectionRequest(list_services='',),) 175 responses = [] 176 async for response in self._stub.ServerReflectionInfo(iter(requests)): 177 responses.append(response) 178 expected_responses = (reflection_pb2.ServerReflectionResponse( 179 valid_host='', 180 list_services_response=reflection_pb2.ListServiceResponse( 181 service=tuple( 182 reflection_pb2.ServiceResponse(name=name) 183 for name in _SERVICE_NAMES))),) 184 self.assertSequenceEqual(expected_responses, responses) 185 186 def test_reflection_service_name(self): 187 self.assertEqual(reflection.SERVICE_NAME, 188 'grpc.reflection.v1alpha.ServerReflection') 189 190 191if __name__ == '__main__': 192 logging.basicConfig(level=logging.DEBUG) 193 unittest.main(verbosity=2) 194