• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
19from google.protobuf import descriptor_pb2
20import grpc
21from grpc.experimental import aio
22from grpc_reflection.v1alpha import reflection
23from grpc_reflection.v1alpha import reflection_pb2
24from grpc_reflection.v1alpha import reflection_pb2_grpc
25
26from src.proto.grpc.testing import empty_pb2
27from src.proto.grpc.testing.proto2 import empty2_extensions_pb2
28from src.proto.grpc.testing.proto2 import empty2_pb2
29from tests_aio.unit._test_base import AioTestBase
30
31_EMPTY_PROTO_FILE_NAME = "src/proto/grpc/testing/empty.proto"
32_EMPTY_PROTO_SYMBOL_NAME = "grpc.testing.Empty"
33_SERVICE_NAMES = (
34    "Angstrom",
35    "Bohr",
36    "Curie",
37    "Dyson",
38    "Einstein",
39    "Feynman",
40    "Galilei",
41)
42_EMPTY_EXTENSIONS_SYMBOL_NAME = "grpc.testing.proto2.EmptyWithExtensions"
43_EMPTY_EXTENSIONS_NUMBERS = (
44    124,
45    125,
46    126,
47    127,
48    128,
49)
50
51
52def _file_descriptor_to_proto(descriptor):
53    proto = descriptor_pb2.FileDescriptorProto()
54    descriptor.CopyToProto(proto)
55    return proto.SerializeToString()
56
57
58class ReflectionServicerTest(AioTestBase):
59    async def setUp(self):
60        self._server = aio.server()
61        reflection.enable_server_reflection(_SERVICE_NAMES, self._server)
62        port = self._server.add_insecure_port("[::]:0")
63        await self._server.start()
64
65        self._channel = aio.insecure_channel("localhost:%d" % port)
66        self._stub = reflection_pb2_grpc.ServerReflectionStub(self._channel)
67
68    async def tearDown(self):
69        await self._server.stop(None)
70        await self._channel.close()
71
72    async def test_file_by_name(self):
73        requests = (
74            reflection_pb2.ServerReflectionRequest(
75                file_by_filename=_EMPTY_PROTO_FILE_NAME
76            ),
77            reflection_pb2.ServerReflectionRequest(
78                file_by_filename="i-donut-exist"
79            ),
80        )
81        responses = []
82        async for response in self._stub.ServerReflectionInfo(iter(requests)):
83            responses.append(response)
84        expected_responses = (
85            reflection_pb2.ServerReflectionResponse(
86                valid_host="",
87                file_descriptor_response=reflection_pb2.FileDescriptorResponse(
88                    file_descriptor_proto=(
89                        _file_descriptor_to_proto(empty_pb2.DESCRIPTOR),
90                    )
91                ),
92                original_request=requests[0],
93            ),
94            reflection_pb2.ServerReflectionResponse(
95                valid_host="",
96                error_response=reflection_pb2.ErrorResponse(
97                    error_code=grpc.StatusCode.NOT_FOUND.value[0],
98                    error_message=grpc.StatusCode.NOT_FOUND.value[1].encode(),
99                ),
100                original_request=requests[1],
101            ),
102        )
103        self.assertSequenceEqual(expected_responses, responses)
104
105    async def test_file_by_symbol(self):
106        requests = (
107            reflection_pb2.ServerReflectionRequest(
108                file_containing_symbol=_EMPTY_PROTO_SYMBOL_NAME
109            ),
110            reflection_pb2.ServerReflectionRequest(
111                file_containing_symbol="i.donut.exist.co.uk.org.net.me.name.foo"
112            ),
113        )
114        responses = []
115        async for response in self._stub.ServerReflectionInfo(iter(requests)):
116            responses.append(response)
117        expected_responses = (
118            reflection_pb2.ServerReflectionResponse(
119                valid_host="",
120                file_descriptor_response=reflection_pb2.FileDescriptorResponse(
121                    file_descriptor_proto=(
122                        _file_descriptor_to_proto(empty_pb2.DESCRIPTOR),
123                    )
124                ),
125                original_request=requests[0],
126            ),
127            reflection_pb2.ServerReflectionResponse(
128                valid_host="",
129                error_response=reflection_pb2.ErrorResponse(
130                    error_code=grpc.StatusCode.NOT_FOUND.value[0],
131                    error_message=grpc.StatusCode.NOT_FOUND.value[1].encode(),
132                ),
133                original_request=requests[1],
134            ),
135        )
136        self.assertSequenceEqual(expected_responses, responses)
137
138    async def test_file_containing_extension(self):
139        requests = (
140            reflection_pb2.ServerReflectionRequest(
141                file_containing_extension=reflection_pb2.ExtensionRequest(
142                    containing_type=_EMPTY_EXTENSIONS_SYMBOL_NAME,
143                    extension_number=125,
144                ),
145            ),
146            reflection_pb2.ServerReflectionRequest(
147                file_containing_extension=reflection_pb2.ExtensionRequest(
148                    containing_type="i.donut.exist.co.uk.org.net.me.name.foo",
149                    extension_number=55,
150                ),
151            ),
152        )
153        responses = []
154        async for response in self._stub.ServerReflectionInfo(iter(requests)):
155            responses.append(response)
156        expected_responses = (
157            reflection_pb2.ServerReflectionResponse(
158                valid_host="",
159                file_descriptor_response=reflection_pb2.FileDescriptorResponse(
160                    file_descriptor_proto=(
161                        _file_descriptor_to_proto(
162                            empty2_extensions_pb2.DESCRIPTOR
163                        ),
164                        _file_descriptor_to_proto(empty2_pb2.DESCRIPTOR),
165                    )
166                ),
167                original_request=requests[0],
168            ),
169            reflection_pb2.ServerReflectionResponse(
170                valid_host="",
171                error_response=reflection_pb2.ErrorResponse(
172                    error_code=grpc.StatusCode.NOT_FOUND.value[0],
173                    error_message=grpc.StatusCode.NOT_FOUND.value[1].encode(),
174                ),
175                original_request=requests[1],
176            ),
177        )
178        self.assertSequenceEqual(expected_responses, responses)
179
180    async def test_extension_numbers_of_type(self):
181        requests = (
182            reflection_pb2.ServerReflectionRequest(
183                all_extension_numbers_of_type=_EMPTY_EXTENSIONS_SYMBOL_NAME
184            ),
185            reflection_pb2.ServerReflectionRequest(
186                all_extension_numbers_of_type="i.donut.exist.co.uk.net.name.foo"
187            ),
188        )
189        responses = []
190        async for response in self._stub.ServerReflectionInfo(iter(requests)):
191            responses.append(response)
192        expected_responses = (
193            reflection_pb2.ServerReflectionResponse(
194                valid_host="",
195                all_extension_numbers_response=reflection_pb2.ExtensionNumberResponse(
196                    base_type_name=_EMPTY_EXTENSIONS_SYMBOL_NAME,
197                    extension_number=_EMPTY_EXTENSIONS_NUMBERS,
198                ),
199                original_request=requests[0],
200            ),
201            reflection_pb2.ServerReflectionResponse(
202                valid_host="",
203                error_response=reflection_pb2.ErrorResponse(
204                    error_code=grpc.StatusCode.NOT_FOUND.value[0],
205                    error_message=grpc.StatusCode.NOT_FOUND.value[1].encode(),
206                ),
207                original_request=requests[1],
208            ),
209        )
210        self.assertSequenceEqual(expected_responses, responses)
211
212    async def test_list_services(self):
213        requests = (
214            reflection_pb2.ServerReflectionRequest(
215                list_services="",
216            ),
217        )
218        responses = []
219        async for response in self._stub.ServerReflectionInfo(iter(requests)):
220            responses.append(response)
221        expected_responses = (
222            reflection_pb2.ServerReflectionResponse(
223                valid_host="",
224                list_services_response=reflection_pb2.ListServiceResponse(
225                    service=tuple(
226                        reflection_pb2.ServiceResponse(name=name)
227                        for name in _SERVICE_NAMES
228                    )
229                ),
230                original_request=requests[0],
231            ),
232        )
233        self.assertSequenceEqual(expected_responses, responses)
234
235    def test_reflection_service_name(self):
236        self.assertEqual(
237            reflection.SERVICE_NAME, "grpc.reflection.v1alpha.ServerReflection"
238        )
239
240
241if __name__ == "__main__":
242    logging.basicConfig(level=logging.DEBUG)
243    unittest.main(verbosity=2)
244