• 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 server and client side compression."""
15
16import unittest
17
18import grpc
19from grpc import _grpcio_metadata
20
21from tests.unit import test_common
22from tests.unit.framework.common import test_constants
23
24_UNARY_UNARY = '/test/UnaryUnary'
25_STREAM_STREAM = '/test/StreamStream'
26
27
28def handle_unary(request, servicer_context):
29    servicer_context.send_initial_metadata([('grpc-internal-encoding-request',
30                                             'gzip')])
31    return request
32
33
34def handle_stream(request_iterator, servicer_context):
35    # TODO(issue:#6891) We should be able to remove this loop,
36    # and replace with return; yield
37    servicer_context.send_initial_metadata([('grpc-internal-encoding-request',
38                                             'gzip')])
39    for request in request_iterator:
40        yield request
41
42
43class _MethodHandler(grpc.RpcMethodHandler):
44
45    def __init__(self, request_streaming, response_streaming):
46        self.request_streaming = request_streaming
47        self.response_streaming = response_streaming
48        self.request_deserializer = None
49        self.response_serializer = None
50        self.unary_unary = None
51        self.unary_stream = None
52        self.stream_unary = None
53        self.stream_stream = None
54        if self.request_streaming and self.response_streaming:
55            self.stream_stream = handle_stream
56        elif not self.request_streaming and not self.response_streaming:
57            self.unary_unary = handle_unary
58
59
60class _GenericHandler(grpc.GenericRpcHandler):
61
62    def service(self, handler_call_details):
63        if handler_call_details.method == _UNARY_UNARY:
64            return _MethodHandler(False, False)
65        elif handler_call_details.method == _STREAM_STREAM:
66            return _MethodHandler(True, True)
67        else:
68            return None
69
70
71class CompressionTest(unittest.TestCase):
72
73    def setUp(self):
74        self._server = test_common.test_server()
75        self._server.add_generic_rpc_handlers((_GenericHandler(),))
76        self._port = self._server.add_insecure_port('[::]:0')
77        self._server.start()
78
79    def testUnary(self):
80        request = b'\x00' * 100
81
82        # Client -> server compressed through default client channel compression
83        # settings. Server -> client compressed via server-side metadata setting.
84        # TODO(https://github.com/grpc/grpc/issues/4078): replace the "1" integer
85        # literal with proper use of the public API.
86        compressed_channel = grpc.insecure_channel(
87            'localhost:%d' % self._port,
88            options=[('grpc.default_compression_algorithm', 1)])
89        multi_callable = compressed_channel.unary_unary(_UNARY_UNARY)
90        response = multi_callable(request)
91        self.assertEqual(request, response)
92
93        # Client -> server compressed through client metadata setting. Server ->
94        # client compressed via server-side metadata setting.
95        # TODO(https://github.com/grpc/grpc/issues/4078): replace the "0" integer
96        # literal with proper use of the public API.
97        uncompressed_channel = grpc.insecure_channel(
98            'localhost:%d' % self._port,
99            options=[('grpc.default_compression_algorithm', 0)])
100        multi_callable = compressed_channel.unary_unary(_UNARY_UNARY)
101        response = multi_callable(
102            request, metadata=[('grpc-internal-encoding-request', 'gzip')])
103        self.assertEqual(request, response)
104
105    def testStreaming(self):
106        request = b'\x00' * 100
107
108        # TODO(https://github.com/grpc/grpc/issues/4078): replace the "1" integer
109        # literal with proper use of the public API.
110        compressed_channel = grpc.insecure_channel(
111            'localhost:%d' % self._port,
112            options=[('grpc.default_compression_algorithm', 1)])
113        multi_callable = compressed_channel.stream_stream(_STREAM_STREAM)
114        call = multi_callable(iter([request] * test_constants.STREAM_LENGTH))
115        for response in call:
116            self.assertEqual(request, response)
117
118
119if __name__ == '__main__':
120    unittest.main(verbosity=2)
121