xref: /aosp_15_r20/external/grpc-grpc/test/core/transport/test_suite/call_content.cc (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
1 // Copyright 2023 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 
15 #include "gmock/gmock.h"
16 
17 #include "test/core/transport/test_suite/test.h"
18 
19 using testing::UnorderedElementsAreArray;
20 
21 namespace grpc_core {
22 
23 namespace {
24 class LoweringEncoder {
25  public:
Take()26   std::vector<std::pair<std::string, std::string>> Take() {
27     return std::move(metadata_);
28   }
29 
Encode(const Slice & key,const Slice & value)30   void Encode(const Slice& key, const Slice& value) {
31     metadata_.emplace_back(key.as_string_view(), value.as_string_view());
32   }
33 
34   template <typename Which>
Encode(Which,const typename Which::ValueType & value)35   void Encode(Which, const typename Which::ValueType& value) {
36     metadata_.emplace_back(Which::key(), Which::Encode(value).as_string_view());
37   }
38 
39  private:
40   std::vector<std::pair<std::string, std::string>> metadata_;
41 };
42 
LowerMetadata(const grpc_metadata_batch & metadata)43 std::vector<std::pair<std::string, std::string>> LowerMetadata(
44     const grpc_metadata_batch& metadata) {
45   LoweringEncoder encoder;
46   metadata.Encode(&encoder);
47   return encoder.Take();
48 }
49 
FillMetadata(const std::vector<std::pair<std::string,std::string>> & md,grpc_metadata_batch & out)50 void FillMetadata(const std::vector<std::pair<std::string, std::string>>& md,
51                   grpc_metadata_batch& out) {
52   for (const auto& p : md) {
53     out.Append(p.first, Slice::FromCopiedString(p.second),
54                [&](absl::string_view error, const Slice& value) {
55                  Crash(absl::StrCat(
56                      "Failed to parse metadata for '", p.first, "': ", error,
57                      " value=", absl::CEscape(value.as_string_view())));
58                });
59   }
60 }
61 
62 }  // namespace
63 
TRANSPORT_TEST(UnaryWithSomeContent)64 TRANSPORT_TEST(UnaryWithSomeContent) {
65   SetServerAcceptor();
66   auto initiator = CreateCall();
67   const auto client_initial_metadata = RandomMetadata();
68   const auto server_initial_metadata = RandomMetadata();
69   const auto server_trailing_metadata = RandomMetadata();
70   const auto client_payload = RandomMessage();
71   const auto server_payload = RandomMessage();
72   SpawnTestSeq(
73       initiator, "initiator",
74       [&]() {
75         auto md = Arena::MakePooled<ClientMetadata>();
76         FillMetadata(client_initial_metadata, *md);
77         return initiator.PushClientInitialMetadata(std::move(md));
78       },
79       [&](StatusFlag status) mutable {
80         EXPECT_TRUE(status.ok());
81         return initiator.PushMessage(Arena::MakePooled<Message>(
82             SliceBuffer(Slice::FromCopiedString(client_payload)), 0));
83       },
84       [&](StatusFlag status) mutable {
85         EXPECT_TRUE(status.ok());
86         initiator.FinishSends();
87         return initiator.PullServerInitialMetadata();
88       },
89       [&](ValueOrFailure<absl::optional<ServerMetadataHandle>> md) {
90         EXPECT_TRUE(md.ok());
91         EXPECT_TRUE(md.value().has_value());
92         EXPECT_THAT(LowerMetadata(***md),
93                     UnorderedElementsAreArray(server_initial_metadata));
94         return initiator.PullMessage();
95       },
96       [&](NextResult<MessageHandle> msg) {
97         EXPECT_TRUE(msg.has_value());
98         EXPECT_EQ(msg.value()->payload()->JoinIntoString(), server_payload);
99         return initiator.PullMessage();
100       },
101       [&](NextResult<MessageHandle> msg) {
102         EXPECT_FALSE(msg.has_value());
103         EXPECT_FALSE(msg.cancelled());
104         return initiator.PullServerTrailingMetadata();
105       },
106       [&](ValueOrFailure<ServerMetadataHandle> md) {
107         EXPECT_TRUE(md.ok());
108         EXPECT_THAT(LowerMetadata(**md),
109                     UnorderedElementsAreArray(server_trailing_metadata));
110         return Empty{};
111       });
112   auto handler = TickUntilServerCall();
113   SpawnTestSeq(
114       handler, "handler", [&] { return handler.PullClientInitialMetadata(); },
115       [&](ValueOrFailure<ServerMetadataHandle> md) {
116         EXPECT_TRUE(md.ok());
117         EXPECT_THAT(LowerMetadata(**md),
118                     UnorderedElementsAreArray(client_initial_metadata));
119         return handler.PullMessage();
120       },
121       [&](NextResult<MessageHandle> msg) {
122         EXPECT_TRUE(msg.has_value());
123         EXPECT_EQ(msg.value()->payload()->JoinIntoString(), client_payload);
124         return handler.PullMessage();
125       },
126       [&](NextResult<MessageHandle> msg) {
127         EXPECT_FALSE(msg.has_value());
128         EXPECT_FALSE(msg.cancelled());
129         auto md = Arena::MakePooled<ServerMetadata>();
130         FillMetadata(server_initial_metadata, *md);
131         return handler.PushServerInitialMetadata(std::move(md));
132       },
133       [&](StatusFlag result) mutable {
134         EXPECT_TRUE(result.ok());
135         return handler.PushMessage(Arena::MakePooled<Message>(
136             SliceBuffer(Slice::FromCopiedString(server_payload)), 0));
137       },
138       [&](StatusFlag result) mutable {
139         EXPECT_TRUE(result.ok());
140         auto md = Arena::MakePooled<ServerMetadata>();
141         FillMetadata(server_trailing_metadata, *md);
142         return handler.PushServerTrailingMetadata(std::move(md));
143       },
144       [&](StatusFlag result) mutable {
145         EXPECT_TRUE(result.ok());
146         return Empty{};
147       });
148   WaitForAllPendingWork();
149 }
150 
151 }  // namespace grpc_core
152