• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 //
3 // Copyright 2015 gRPC authors.
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // 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 //
18 
19 #include <grpc/compression.h>
20 #include <grpc/grpc.h>
21 #include <grpc/impl/channel_arg_names.h>
22 #include <grpc/status.h>
23 #include <stdint.h>
24 
25 #include <initializer_list>
26 #include <string>
27 #include <utility>
28 
29 #include "absl/strings/string_view.h"
30 #include "gtest/gtest.h"
31 #include "src/core/lib/channel/channel_args.h"
32 #include "src/core/util/bitset.h"
33 #include "src/core/util/time.h"
34 #include "test/core/end2end/end2end_tests.h"
35 
36 namespace grpc_core {
37 namespace {
38 
39 class TestConfigurator {
40  public:
TestConfigurator(CoreEnd2endTest & test)41   explicit TestConfigurator(CoreEnd2endTest& test) : test_(test) {}
42 
DisableAlgorithmAtServer(grpc_compression_algorithm algorithm)43   TestConfigurator& DisableAlgorithmAtServer(
44       grpc_compression_algorithm algorithm) {
45     server_args_ =
46         server_args_.Set(GRPC_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET,
47                          BitSet<GRPC_COMPRESS_ALGORITHMS_COUNT>()
48                              .SetAll(true)
49                              .Set(algorithm, false)
50                              .ToInt<uint32_t>());
51     return *this;
52   }
53 
ClientDefaultAlgorithm(grpc_compression_algorithm algorithm)54   TestConfigurator& ClientDefaultAlgorithm(
55       grpc_compression_algorithm algorithm) {
56     client_args_ =
57         client_args_.Set(GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM, algorithm);
58     return *this;
59   }
60 
ServerDefaultAlgorithm(grpc_compression_algorithm algorithm)61   TestConfigurator& ServerDefaultAlgorithm(
62       grpc_compression_algorithm algorithm) {
63     server_args_ =
64         server_args_.Set(GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM, algorithm);
65     return *this;
66   }
67 
DecompressInApp()68   TestConfigurator& DecompressInApp() {
69     client_args_ =
70         client_args_.Set(GRPC_ARG_ENABLE_PER_MESSAGE_DECOMPRESSION, false);
71     server_args_ =
72         server_args_.Set(GRPC_ARG_ENABLE_PER_MESSAGE_DECOMPRESSION, false);
73     return *this;
74   }
75 
ExpectedAlgorithmFromClient(grpc_compression_algorithm algorithm)76   TestConfigurator& ExpectedAlgorithmFromClient(
77       grpc_compression_algorithm algorithm) {
78     expected_algorithm_from_client_ = algorithm;
79     return *this;
80   }
81 
ExpectedAlgorithmFromServer(grpc_compression_algorithm algorithm)82   TestConfigurator& ExpectedAlgorithmFromServer(
83       grpc_compression_algorithm algorithm) {
84     expected_algorithm_from_server_ = algorithm;
85     return *this;
86   }
87 
DisabledAlgorithmTest()88   void DisabledAlgorithmTest() {
89     Init();
90     auto c = test_.NewClientCall("/foo").Timeout(Duration::Minutes(1)).Create();
91     auto s = test_.RequestCall(101);
92     IncomingMetadata server_initial_metadata;
93     IncomingStatusOnClient server_status;
94     c.NewBatch(1)
95         .SendInitialMetadata({})
96         .SendMessage(std::string(1024, 'x'))
97         .SendCloseFromClient()
98         .RecvInitialMetadata(server_initial_metadata)
99         .RecvStatusOnClient(server_status);
100     test_.Expect(101, true);
101     test_.Expect(1, true);
102     test_.Step();
103     IncomingMessage client_message;
104     s.NewBatch(102).SendInitialMetadata({}).RecvMessage(client_message);
105     IncomingCloseOnServer client_close;
106     test_.Expect(102, false);
107     s.NewBatch(103).RecvCloseOnServer(client_close);
108     test_.Expect(103, true);
109     test_.Step();
110     // call was cancelled (closed) ...
111     EXPECT_NE(client_close.was_cancelled(), 0);
112     // with a certain error
113     EXPECT_EQ(server_status.status(), GRPC_STATUS_UNIMPLEMENTED);
114     // and we expect a specific reason for it
115     EXPECT_EQ(server_status.message(),
116               "Compression algorithm 'gzip' is disabled.");
117     EXPECT_EQ(s.method(), "/foo");
118   }
119 
RequestWithPayload(uint32_t client_send_flags_bitmask,std::initializer_list<std::pair<absl::string_view,absl::string_view>> client_init_metadata)120   void RequestWithPayload(
121       uint32_t client_send_flags_bitmask,
122       std::initializer_list<std::pair<absl::string_view, absl::string_view>>
123           client_init_metadata) {
124     Init();
125     auto c =
126         test_.NewClientCall("/foo").Timeout(Duration::Seconds(30)).Create();
127     IncomingStatusOnClient server_status;
128     IncomingMetadata server_initial_metadata;
129     c.NewBatch(1)
130         .SendInitialMetadata(client_init_metadata)
131         .RecvInitialMetadata(server_initial_metadata)
132         .RecvStatusOnClient(server_status);
133     auto s = test_.RequestCall(100);
134     test_.Expect(100, true);
135     test_.Step();
136     EXPECT_TRUE(s.GetEncodingsAcceptedByPeer().all());
137     IncomingCloseOnServer client_close;
138     s.NewBatch(101).SendInitialMetadata({}).RecvCloseOnServer(client_close);
139     for (int i = 0; i < 2; i++) {
140       c.NewBatch(2).SendMessage(std::string(1024, 'x'),
141                                 client_send_flags_bitmask);
142       test_.Expect(2, true);
143       IncomingMessage client_message;
144       s.NewBatch(102).RecvMessage(client_message);
145       test_.Expect(102, true);
146       test_.Step();
147       EXPECT_EQ(client_message.byte_buffer_type(), GRPC_BB_RAW);
148       EXPECT_EQ(client_message.payload(), std::string(1024, 'x'));
149       EXPECT_EQ(client_message.compression(), expected_algorithm_from_client_);
150       s.NewBatch(103).SendMessage(std::string(1024, 'y'));
151       IncomingMessage server_message;
152       c.NewBatch(3).RecvMessage(server_message);
153       test_.Expect(103, true);
154       test_.Expect(3, true);
155       test_.Step();
156       EXPECT_EQ(server_message.byte_buffer_type(), GRPC_BB_RAW);
157       EXPECT_EQ(server_message.payload(), std::string(1024, 'y'));
158       EXPECT_EQ(server_message.compression(), expected_algorithm_from_server_);
159     }
160     c.NewBatch(4).SendCloseFromClient();
161     s.NewBatch(104).SendStatusFromServer(GRPC_STATUS_OK, "xyz", {});
162     test_.Expect(1, true);
163     test_.Expect(4, true);
164     test_.Expect(101, true);
165     test_.Expect(104, true);
166     test_.Step();
167     EXPECT_EQ(server_status.status(), GRPC_STATUS_OK);
168     EXPECT_EQ(server_status.message(), "xyz");
169     EXPECT_EQ(s.method(), "/foo");
170     EXPECT_FALSE(client_close.was_cancelled());
171   }
172 
RequestWithSendMessageBeforeInitialMetadata()173   void RequestWithSendMessageBeforeInitialMetadata() {
174     Init();
175     auto c =
176         test_.NewClientCall("/foo").Timeout(Duration::Seconds(30)).Create();
177     c.NewBatch(2).SendMessage(std::string(1024, 'x'));
178     test_.Expect(2, true);
179     IncomingStatusOnClient server_status;
180     IncomingMetadata server_initial_metadata;
181     c.NewBatch(1)
182         .SendInitialMetadata({})
183         .RecvInitialMetadata(server_initial_metadata)
184         .RecvStatusOnClient(server_status);
185     auto s = test_.RequestCall(100);
186     test_.Expect(100, true);
187     test_.Step();
188     EXPECT_TRUE(s.GetEncodingsAcceptedByPeer().all());
189     IncomingCloseOnServer client_close;
190     s.NewBatch(101).SendInitialMetadata({}).RecvCloseOnServer(client_close);
191     for (int i = 0; i < 2; i++) {
192       if (i > 0) {
193         c.NewBatch(2).SendMessage(std::string(1024, 'x'));
194         test_.Expect(2, true);
195       }
196       IncomingMessage client_message;
197       s.NewBatch(102).RecvMessage(client_message);
198       test_.Expect(102, true);
199       test_.Step();
200       EXPECT_EQ(client_message.byte_buffer_type(), GRPC_BB_RAW);
201       EXPECT_EQ(client_message.payload(), std::string(1024, 'x'));
202       EXPECT_EQ(client_message.compression(), expected_algorithm_from_client_);
203       s.NewBatch(103).SendMessage(std::string(1024, 'y'));
204       IncomingMessage server_message;
205       c.NewBatch(3).RecvMessage(server_message);
206       test_.Expect(103, true);
207       test_.Expect(3, true);
208       test_.Step();
209       EXPECT_EQ(server_message.byte_buffer_type(), GRPC_BB_RAW);
210       EXPECT_EQ(server_message.payload(), std::string(1024, 'y'));
211       EXPECT_EQ(server_message.compression(), expected_algorithm_from_server_);
212     }
213     c.NewBatch(4).SendCloseFromClient();
214     s.NewBatch(104).SendStatusFromServer(GRPC_STATUS_OK, "xyz", {});
215     test_.Expect(1, true);
216     test_.Expect(4, true);
217     test_.Expect(101, true);
218     test_.Expect(104, true);
219     test_.Step();
220     EXPECT_EQ(server_status.status(), GRPC_STATUS_OK);
221     EXPECT_EQ(server_status.message(), "xyz");
222     EXPECT_EQ(s.method(), "/foo");
223     EXPECT_FALSE(client_close.was_cancelled());
224   }
225 
RequestWithServerLevel(grpc_compression_level server_compression_level)226   void RequestWithServerLevel(grpc_compression_level server_compression_level) {
227     Init();
228     auto c = test_.NewClientCall("/foo").Timeout(Duration::Minutes(1)).Create();
229     IncomingStatusOnClient server_status;
230     IncomingMetadata server_initial_metadata;
231     c.NewBatch(1)
232         .SendInitialMetadata({})
233         .RecvInitialMetadata(server_initial_metadata)
234         .RecvStatusOnClient(server_status);
235     auto s = test_.RequestCall(100);
236     test_.Expect(100, true);
237     test_.Step();
238     EXPECT_TRUE(s.GetEncodingsAcceptedByPeer().all());
239     IncomingCloseOnServer client_close;
240     s.NewBatch(101)
241         .SendInitialMetadata({}, 0, server_compression_level)
242         .RecvCloseOnServer(client_close);
243     for (int i = 0; i < 2; i++) {
244       c.NewBatch(2).SendMessage(std::string(1024, 'x'));
245       test_.Expect(2, true);
246       IncomingMessage client_message;
247       s.NewBatch(102).RecvMessage(client_message);
248       test_.Expect(102, true);
249       test_.Step();
250       EXPECT_EQ(client_message.byte_buffer_type(), GRPC_BB_RAW);
251       EXPECT_EQ(client_message.payload(), std::string(1024, 'x'));
252       EXPECT_EQ(client_message.compression(), expected_algorithm_from_client_);
253       s.NewBatch(103).SendMessage(std::string(1024, 'y'));
254       IncomingMessage server_message;
255       c.NewBatch(3).RecvMessage(server_message);
256       test_.Expect(103, true);
257       test_.Expect(3, true);
258       test_.Step();
259       EXPECT_EQ(server_message.byte_buffer_type(), GRPC_BB_RAW);
260       EXPECT_EQ(server_message.payload(), std::string(1024, 'y'));
261       EXPECT_EQ(server_message.compression(), expected_algorithm_from_server_);
262     }
263     c.NewBatch(4).SendCloseFromClient();
264     s.NewBatch(104).SendStatusFromServer(GRPC_STATUS_OK, "xyz", {});
265     test_.Expect(1, true);
266     test_.Expect(4, true);
267     test_.Expect(101, true);
268     test_.Expect(104, true);
269     test_.Step();
270     EXPECT_EQ(server_status.status(), GRPC_STATUS_OK);
271     EXPECT_EQ(server_status.message(), "xyz");
272     EXPECT_EQ(s.method(), "/foo");
273     EXPECT_FALSE(client_close.was_cancelled());
274   }
275 
276  private:
Init()277   void Init() {
278     test_.InitClient(client_args_);
279     test_.InitServer(server_args_);
280   }
281 
282   CoreEnd2endTest& test_;
283   ChannelArgs client_args_ = ChannelArgs().Set(
284       GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM, GRPC_COMPRESS_NONE);
285   ChannelArgs server_args_ = ChannelArgs().Set(
286       GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM, GRPC_COMPRESS_NONE);
287   grpc_compression_algorithm expected_algorithm_from_client_ =
288       GRPC_COMPRESS_NONE;
289   grpc_compression_algorithm expected_algorithm_from_server_ =
290       GRPC_COMPRESS_NONE;
291 };
292 
CORE_END2END_TEST(Http2SingleHopTest,DisabledAlgorithmDecompressInCore)293 CORE_END2END_TEST(Http2SingleHopTest, DisabledAlgorithmDecompressInCore) {
294   TestConfigurator(*this)
295       .ClientDefaultAlgorithm(GRPC_COMPRESS_GZIP)
296       .DisableAlgorithmAtServer(GRPC_COMPRESS_GZIP)
297       .DisabledAlgorithmTest();
298 }
299 
CORE_END2END_TEST(Http2SingleHopTest,DisabledAlgorithmDecompressInApp)300 CORE_END2END_TEST(Http2SingleHopTest, DisabledAlgorithmDecompressInApp) {
301   TestConfigurator(*this)
302       .ClientDefaultAlgorithm(GRPC_COMPRESS_GZIP)
303       .DisableAlgorithmAtServer(GRPC_COMPRESS_GZIP)
304       .DecompressInApp()
305       .DisabledAlgorithmTest();
306 }
307 
CORE_END2END_TEST(Http2SingleHopTest,RequestWithExceptionallyUncompressedPayloadDecompressInCore)308 CORE_END2END_TEST(Http2SingleHopTest,
309                   RequestWithExceptionallyUncompressedPayloadDecompressInCore) {
310   TestConfigurator(*this)
311       .ClientDefaultAlgorithm(GRPC_COMPRESS_GZIP)
312       .ServerDefaultAlgorithm(GRPC_COMPRESS_GZIP)
313       .RequestWithPayload(GRPC_WRITE_NO_COMPRESS, {});
314 }
315 
CORE_END2END_TEST(Http2SingleHopTest,RequestWithExceptionallyUncompressedPayloadDecompressInApp)316 CORE_END2END_TEST(Http2SingleHopTest,
317                   RequestWithExceptionallyUncompressedPayloadDecompressInApp) {
318   TestConfigurator(*this)
319       .ClientDefaultAlgorithm(GRPC_COMPRESS_GZIP)
320       .ServerDefaultAlgorithm(GRPC_COMPRESS_GZIP)
321       .DecompressInApp()
322       .ExpectedAlgorithmFromServer(GRPC_COMPRESS_GZIP)
323       .RequestWithPayload(GRPC_WRITE_NO_COMPRESS, {});
324 }
325 
CORE_END2END_TEST(Http2SingleHopTest,RequestWithUncompressedPayloadDecompressInCore)326 CORE_END2END_TEST(Http2SingleHopTest,
327                   RequestWithUncompressedPayloadDecompressInCore) {
328   TestConfigurator(*this).RequestWithPayload(0, {});
329 }
330 
CORE_END2END_TEST(Http2SingleHopTest,RequestWithUncompressedPayloadDecompressInApp)331 CORE_END2END_TEST(Http2SingleHopTest,
332                   RequestWithUncompressedPayloadDecompressInApp) {
333   TestConfigurator(*this).DecompressInApp().RequestWithPayload(0, {});
334 }
335 
CORE_END2END_TEST(Http2SingleHopTest,RequestWithCompressedPayloadDecompressInCore)336 CORE_END2END_TEST(Http2SingleHopTest,
337                   RequestWithCompressedPayloadDecompressInCore) {
338   TestConfigurator(*this)
339       .ClientDefaultAlgorithm(GRPC_COMPRESS_GZIP)
340       .ServerDefaultAlgorithm(GRPC_COMPRESS_GZIP)
341       .RequestWithPayload(0, {});
342 }
343 
CORE_END2END_TEST(Http2SingleHopTest,RequestWithCompressedPayloadDecompressInApp)344 CORE_END2END_TEST(Http2SingleHopTest,
345                   RequestWithCompressedPayloadDecompressInApp) {
346   TestConfigurator(*this)
347       .ClientDefaultAlgorithm(GRPC_COMPRESS_GZIP)
348       .ServerDefaultAlgorithm(GRPC_COMPRESS_GZIP)
349       .DecompressInApp()
350       .ExpectedAlgorithmFromClient(GRPC_COMPRESS_GZIP)
351       .ExpectedAlgorithmFromServer(GRPC_COMPRESS_GZIP)
352       .RequestWithPayload(0, {});
353 }
354 
CORE_END2END_TEST(Http2SingleHopTest,RequestWithSendMessageBeforeInitialMetadataDecompressInCore)355 CORE_END2END_TEST(Http2SingleHopTest,
356                   RequestWithSendMessageBeforeInitialMetadataDecompressInCore) {
357   TestConfigurator(*this)
358       .ClientDefaultAlgorithm(GRPC_COMPRESS_GZIP)
359       .ServerDefaultAlgorithm(GRPC_COMPRESS_GZIP)
360       .RequestWithSendMessageBeforeInitialMetadata();
361 }
362 
CORE_END2END_TEST(Http2SingleHopTest,RequestWithSendMessageBeforeInitialMetadataDecompressInApp)363 CORE_END2END_TEST(Http2SingleHopTest,
364                   RequestWithSendMessageBeforeInitialMetadataDecompressInApp) {
365   TestConfigurator(*this)
366       .ClientDefaultAlgorithm(GRPC_COMPRESS_GZIP)
367       .ServerDefaultAlgorithm(GRPC_COMPRESS_GZIP)
368       .DecompressInApp()
369       .ExpectedAlgorithmFromClient(GRPC_COMPRESS_GZIP)
370       .ExpectedAlgorithmFromServer(GRPC_COMPRESS_GZIP)
371       .RequestWithSendMessageBeforeInitialMetadata();
372 }
373 
CORE_END2END_TEST(Http2SingleHopTest,RequestWithServerLevelDecompressInCore)374 CORE_END2END_TEST(Http2SingleHopTest, RequestWithServerLevelDecompressInCore) {
375   TestConfigurator(*this).RequestWithServerLevel(GRPC_COMPRESS_LEVEL_HIGH);
376 }
377 
CORE_END2END_TEST(Http2SingleHopTest,RequestWithServerLevelDecompressInApp)378 CORE_END2END_TEST(Http2SingleHopTest, RequestWithServerLevelDecompressInApp) {
379   TestConfigurator(*this)
380       .DecompressInApp()
381       .ExpectedAlgorithmFromServer(GRPC_COMPRESS_DEFLATE)
382       .RequestWithServerLevel(GRPC_COMPRESS_LEVEL_HIGH);
383 }
384 
CORE_END2END_TEST(Http2SingleHopTest,RequestWithCompressedPayloadMetadataOverrideNoneToGzipDecompressInCore)385 CORE_END2END_TEST(
386     Http2SingleHopTest,
387     RequestWithCompressedPayloadMetadataOverrideNoneToGzipDecompressInCore) {
388   TestConfigurator(*this).RequestWithPayload(
389       0, {{"grpc-internal-encoding-request", "gzip"}});
390 }
391 
CORE_END2END_TEST(Http2SingleHopTest,RequestWithCompressedPayloadMetadataOverrideNoneToGzipDecompressInApp)392 CORE_END2END_TEST(
393     Http2SingleHopTest,
394     RequestWithCompressedPayloadMetadataOverrideNoneToGzipDecompressInApp) {
395   TestConfigurator(*this)
396       .DecompressInApp()
397       .ExpectedAlgorithmFromClient(GRPC_COMPRESS_GZIP)
398       .RequestWithPayload(0, {{"grpc-internal-encoding-request", "gzip"}});
399 }
400 
CORE_END2END_TEST(Http2SingleHopTest,RequestWithCompressedPayloadMetadataOverrideDeflateToGzipDecompressInCore)401 CORE_END2END_TEST(
402     Http2SingleHopTest,
403     RequestWithCompressedPayloadMetadataOverrideDeflateToGzipDecompressInCore) {
404   TestConfigurator(*this)
405       .ClientDefaultAlgorithm(GRPC_COMPRESS_DEFLATE)
406       .RequestWithPayload(0, {{"grpc-internal-encoding-request", "gzip"}});
407 }
408 
CORE_END2END_TEST(Http2SingleHopTest,RequestWithCompressedPayloadMetadataOverrideDeflateToGzipDecompressInApp)409 CORE_END2END_TEST(
410     Http2SingleHopTest,
411     RequestWithCompressedPayloadMetadataOverrideDeflateToGzipDecompressInApp) {
412   TestConfigurator(*this)
413       .ClientDefaultAlgorithm(GRPC_COMPRESS_DEFLATE)
414       .DecompressInApp()
415       .ExpectedAlgorithmFromClient(GRPC_COMPRESS_GZIP)
416       .RequestWithPayload(0, {{"grpc-internal-encoding-request", "gzip"}});
417 }
418 
CORE_END2END_TEST(Http2SingleHopTest,RequestWithCompressedPayloadMetadataOverrideDeflateToIdentityDecompressInCore)419 CORE_END2END_TEST(
420     Http2SingleHopTest,
421     RequestWithCompressedPayloadMetadataOverrideDeflateToIdentityDecompressInCore) {
422   TestConfigurator(*this)
423       .ClientDefaultAlgorithm(GRPC_COMPRESS_DEFLATE)
424       .RequestWithPayload(0, {{"grpc-internal-encoding-request", "identity"}});
425 }
426 
CORE_END2END_TEST(Http2SingleHopTest,RequestWithCompressedPayloadMetadataOverrideDeflateToIdentityDecompressInApp)427 CORE_END2END_TEST(
428     Http2SingleHopTest,
429     RequestWithCompressedPayloadMetadataOverrideDeflateToIdentityDecompressInApp) {
430   TestConfigurator(*this)
431       .ClientDefaultAlgorithm(GRPC_COMPRESS_DEFLATE)
432       .DecompressInApp()
433       .RequestWithPayload(0, {{"grpc-internal-encoding-request", "identity"}});
434 }
435 
436 }  // namespace
437 }  // namespace grpc_core
438