xref: /aosp_15_r20/external/grpc-grpc/test/core/end2end/tests/retry_send_initial_metadata_refs.cc (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
1 //
2 //
3 // Copyright 2017 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 <string>
20 
21 #include "absl/types/optional.h"
22 #include "gtest/gtest.h"
23 
24 #include <grpc/impl/channel_arg_names.h>
25 #include <grpc/slice.h>
26 #include <grpc/status.h>
27 
28 #include "src/core/lib/channel/channel_args.h"
29 #include "src/core/lib/gprpp/time.h"
30 #include "test/core/end2end/end2end_tests.h"
31 
32 namespace grpc_core {
33 namespace {
34 
35 // Tests that we hold refs to send_initial_metadata payload while
36 // cached, even after the caller has released its refs:
37 // - 2 retries allowed for ABORTED status
38 // - first attempt returns ABORTED
39 // - second attempt returns OK
CORE_END2END_TEST(RetryTest,RetrySendInitialMetadataRefs)40 CORE_END2END_TEST(RetryTest, RetrySendInitialMetadataRefs) {
41   InitServer(ChannelArgs());
42   InitClient(ChannelArgs().Set(
43       GRPC_ARG_SERVICE_CONFIG,
44       "{\n"
45       "  \"methodConfig\": [ {\n"
46       "    \"name\": [\n"
47       "      { \"service\": \"service\", \"method\": \"method\" }\n"
48       "    ],\n"
49       "    \"retryPolicy\": {\n"
50       "      \"maxAttempts\": 3,\n"
51       "      \"initialBackoff\": \"1s\",\n"
52       "      \"maxBackoff\": \"120s\",\n"
53       "      \"backoffMultiplier\": 1.6,\n"
54       "      \"retryableStatusCodes\": [ \"ABORTED\" ]\n"
55       "    }\n"
56       "  } ]\n"
57       "}"));
58   auto c =
59       NewClientCall("/service/method").Timeout(Duration::Seconds(5)).Create();
60   EXPECT_NE(c.GetPeer(), absl::nullopt);
61   c.NewBatch(1)
62       .SendInitialMetadata(
63           {// First element is short enough for slices to be inlined.
64            {"foo", "bar"},
65            // Second element requires slice allocation.
66            {std::string(GRPC_SLICE_INLINED_SIZE + 1, 'x'),
67             std::string(GRPC_SLICE_INLINED_SIZE + 1, 'y')}})
68       .SendMessage("foo")
69       .SendCloseFromClient();
70   Expect(1, true);
71   Step();
72   IncomingMessage server_message;
73   IncomingMetadata server_initial_metadata;
74   IncomingStatusOnClient server_status;
75   c.NewBatch(2)
76       .RecvMessage(server_message)
77       .RecvInitialMetadata(server_initial_metadata)
78       .RecvStatusOnClient(server_status);
79   auto s = RequestCall(101);
80   Expect(101, true);
81   Step();
82   // Make sure the "grpc-previous-rpc-attempts" header was not sent in the
83   // initial attempt.
84   EXPECT_EQ(s.GetInitialMetadata("grpc-previous-rpc-attempts"), absl::nullopt);
85   EXPECT_NE(s.GetPeer(), absl::nullopt);
86   EXPECT_NE(c.GetPeer(), absl::nullopt);
87   IncomingCloseOnServer client_close;
88   s.NewBatch(102)
89       .SendInitialMetadata({})
90       .SendStatusFromServer(GRPC_STATUS_ABORTED, "xyz", {})
91       .RecvCloseOnServer(client_close);
92   Expect(102, true);
93   Step();
94   auto s2 = RequestCall(201);
95   Expect(201, true);
96   Step();
97   // Make sure the "grpc-previous-rpc-attempts" header was sent in the retry.
98   EXPECT_EQ(s2.GetInitialMetadata("grpc-previous-rpc-attempts"), "1");
99   // It should also contain the initial metadata, even though the client
100   // freed it already.
101   EXPECT_EQ(s2.GetInitialMetadata("foo"), "bar");
102   EXPECT_EQ(
103       s2.GetInitialMetadata(std::string(GRPC_SLICE_INLINED_SIZE + 1, 'x')),
104       std::string(GRPC_SLICE_INLINED_SIZE + 1, 'y'));
105   EXPECT_NE(s.GetPeer(), absl::nullopt);
106   EXPECT_NE(c.GetPeer(), absl::nullopt);
107   IncomingMessage client_message;
108   s2.NewBatch(202).RecvMessage(client_message);
109   IncomingCloseOnServer client_close2;
110   s2.NewBatch(203)
111       .SendInitialMetadata({})
112       .SendMessage("bar")
113       .SendStatusFromServer(GRPC_STATUS_OK, "xyz", {})
114       .RecvCloseOnServer(client_close2);
115   Expect(202, true);
116   Expect(203, true);
117   Expect(2, true);
118   Step();
119   EXPECT_EQ(server_status.status(), GRPC_STATUS_OK);
120   EXPECT_EQ(server_status.message(), "xyz");
121   EXPECT_EQ(s.method(), "/service/method");
122   EXPECT_FALSE(client_close.was_cancelled());
123 }
124 
125 }  // namespace
126 }  // namespace grpc_core
127