wire_reader_test.cc
Go to the documentation of this file.
1 // Copyright 2021 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 // Unit tests for WireReaderImpl.
16 //
17 // WireReaderImpl is responsible for turning incoming transactions into
18 // top-level metadata. The following tests verify that the interactions between
19 // WireReaderImpl and both the output (readable) parcel and the transport stream
20 // receiver are correct in all possible situations.
21 
22 #include <memory>
23 #include <string>
24 #include <thread>
25 #include <utility>
26 
27 #include <gtest/gtest.h>
28 
29 #include "absl/memory/memory.h"
30 
32 
36 
37 namespace grpc_binder {
38 
42 using ::testing::StrictMock;
43 
44 namespace {
45 
46 class WireReaderTest : public ::testing::Test {
47  protected:
48  void SetUp() override { SetUp(true); }
49  void SetUp(bool is_client) {
51  std::make_shared<StrictMock<MockTransportStreamReceiver>>();
52  wire_reader_ = std::make_shared<WireReaderImpl>(
53  transport_stream_receiver_, is_client,
54  std::make_shared<
56  }
57 
58  void ExpectReadInt32(int result) {
60  .WillOnce(DoAll(SetArgPointee<0>(result), Return(absl::OkStatus())));
61  }
62 
63  void ExpectReadByteArray(const std::string& buffer) {
64  ExpectReadInt32(buffer.length());
65  if (!buffer.empty()) {
66  EXPECT_CALL(mock_readable_parcel_, ReadByteArray)
67  .WillOnce([buffer](std::string* data) {
68  *data = buffer;
69  return absl::OkStatus();
70  });
71  }
72  }
73 
74  void ExpectReadString(const std::string& str) {
76  .WillOnce([str](std::string* out) {
77  *out = str;
78  return absl::OkStatus();
79  });
80  }
81 
82  void UnblockSetupTransport() {
83  // SETUP_TRANSPORT should finish before we can proceed with any other
84  // requests and streaming calls. The MockBinder will construct a
85  // MockTransactionReceiver, which will then sends SETUP_TRANSPORT request
86  // back to us.
87  wire_reader_->SetupTransport(absl::make_unique<MockBinder>());
88  }
89 
90  template <typename T>
91  absl::Status CallProcessTransaction(T tx_code) {
92  return wire_reader_->ProcessTransaction(
94  /*uid=*/0);
95  }
96 
97  std::shared_ptr<StrictMock<MockTransportStreamReceiver>>
99  std::shared_ptr<WireReaderImpl> wire_reader_;
100  MockReadableParcel mock_readable_parcel_;
101 };
102 
103 MATCHER_P(StatusOrStrEq, target, "") {
104  if (!arg.ok()) return false;
105  return arg.value() == target;
106 }
107 
108 MATCHER_P(StatusOrContainerEq, target, "") {
109  if (!arg.ok()) return false;
110  return arg.value() == target;
111 }
112 
113 } // namespace
114 
115 TEST_F(WireReaderTest, SetupTransport) {
116  auto mock_binder = absl::make_unique<MockBinder>();
117  MockBinder& mock_binder_ref = *mock_binder;
118 
119  ::testing::InSequence sequence;
120  EXPECT_CALL(mock_binder_ref, Initialize);
121  EXPECT_CALL(mock_binder_ref, PrepareTransaction);
122  const MockReadableParcel mock_readable_parcel;
123  EXPECT_CALL(mock_binder_ref, GetWritableParcel);
124 
125  // Write version.
126  EXPECT_CALL(mock_binder_ref.GetWriter(), WriteInt32(1));
127 
128  wire_reader_->SetupTransport(std::move(mock_binder));
129 }
130 
131 TEST_F(WireReaderTest, ProcessTransactionControlMessageSetupTransport) {
132  ::testing::InSequence sequence;
133  UnblockSetupTransport();
134 }
135 
136 TEST_F(WireReaderTest, ProcessTransactionControlMessagePingResponse) {
137  ::testing::InSequence sequence;
138  UnblockSetupTransport();
140  EXPECT_TRUE(
141  CallProcessTransaction(BinderTransportTxCode::PING_RESPONSE).ok());
142 }
143 
144 TEST_F(WireReaderTest, ProcessTransactionServerRpcDataEmptyFlagIgnored) {
145  ::testing::InSequence sequence;
146  UnblockSetupTransport();
147 
148  // first transaction: empty flag
149  ExpectReadInt32(0);
150  // Won't further read sequence number.
151  EXPECT_TRUE(CallProcessTransaction(kFirstCallId).ok());
152 }
153 
154 TEST_F(WireReaderTest,
155  ProcessTransactionServerRpcDataFlagPrefixWithoutMetadata) {
156  ::testing::InSequence sequence;
157  UnblockSetupTransport();
158 
159  // flag
160  ExpectReadInt32(kFlagPrefix);
161  // sequence number
162  ExpectReadInt32(0);
163 
164  // count
165  ExpectReadInt32(0);
166  EXPECT_CALL(
168  NotifyRecvInitialMetadata(kFirstCallId, StatusOrContainerEq(Metadata{})));
169 
170  EXPECT_TRUE(CallProcessTransaction(kFirstCallId).ok());
171 }
172 
173 TEST_F(WireReaderTest, ProcessTransactionServerRpcDataFlagPrefixWithMetadata) {
174  ::testing::InSequence sequence;
175  UnblockSetupTransport();
176 
177  // flag
178  ExpectReadInt32(kFlagPrefix);
179  // sequence number
180  ExpectReadInt32(0);
181 
182  const std::vector<std::pair<std::string, std::string>> kMetadata = {
183  {"", ""},
184  {"", "value"},
185  {"key", ""},
186  {"key", "value"},
187  {"another-key", "another-value"},
188  };
189 
190  // count
191  ExpectReadInt32(kMetadata.size());
192  for (const auto& md : kMetadata) {
193  // metadata key
194  ExpectReadByteArray(md.first);
195  // metadata val
196  // TODO(waynetu): metadata value can also be "parcelable".
197  ExpectReadByteArray(md.second);
198  }
199  EXPECT_CALL(
201  NotifyRecvInitialMetadata(kFirstCallId, StatusOrContainerEq(kMetadata)));
202 
203  EXPECT_TRUE(CallProcessTransaction(kFirstCallId).ok());
204 }
205 
206 TEST_F(WireReaderTest, ProcessTransactionServerRpcDataFlagMessageDataNonEmpty) {
207  ::testing::InSequence sequence;
208  UnblockSetupTransport();
209 
210  // flag
211  ExpectReadInt32(kFlagMessageData);
212  // sequence number
213  ExpectReadInt32(0);
214 
215  // message data
216  // TODO(waynetu): message data can also be "parcelable".
217  const std::string kMessageData = "message data";
218  ExpectReadByteArray(kMessageData);
220  NotifyRecvMessage(kFirstCallId, StatusOrStrEq(kMessageData)));
221 
222  EXPECT_TRUE(CallProcessTransaction(kFirstCallId).ok());
223 }
224 
225 TEST_F(WireReaderTest, ProcessTransactionServerRpcDataFlagMessageDataEmpty) {
226  ::testing::InSequence sequence;
227  UnblockSetupTransport();
228 
229  // flag
230  ExpectReadInt32(kFlagMessageData);
231  // sequence number
232  ExpectReadInt32(0);
233 
234  // message data
235  // TODO(waynetu): message data can also be "parcelable".
236  const std::string kMessageData = "";
237  ExpectReadByteArray(kMessageData);
239  NotifyRecvMessage(kFirstCallId, StatusOrStrEq(kMessageData)));
240 
241  EXPECT_TRUE(CallProcessTransaction(kFirstCallId).ok());
242 }
243 
244 TEST_F(WireReaderTest, ProcessTransactionServerRpcDataFlagSuffixWithStatus) {
245  ::testing::InSequence sequence;
246  UnblockSetupTransport();
247 
248  constexpr int kStatus = 0x1234;
249  // flag
250  ExpectReadInt32(kFlagSuffix | kFlagStatusDescription | (kStatus << 16));
251  // sequence number
252  ExpectReadInt32(0);
253  // status description
254  EXPECT_CALL(mock_readable_parcel_, ReadString);
255  // metadata count
256  ExpectReadInt32(0);
258  NotifyRecvTrailingMetadata(
259  kFirstCallId, StatusOrContainerEq(Metadata{}), kStatus));
260 
261  EXPECT_TRUE(CallProcessTransaction(kFirstCallId).ok());
262 }
263 
264 TEST_F(WireReaderTest, ProcessTransactionServerRpcDataFlagSuffixWithoutStatus) {
265  ::testing::InSequence sequence;
266  UnblockSetupTransport();
267 
268  // flag
269  ExpectReadInt32(kFlagSuffix);
270  // sequence number
271  ExpectReadInt32(0);
272  // No status description
273  // metadata count
274  ExpectReadInt32(0);
276  NotifyRecvTrailingMetadata(kFirstCallId,
277  StatusOrContainerEq(Metadata{}), 0));
278 
279  EXPECT_TRUE(CallProcessTransaction(kFirstCallId).ok());
280 }
281 
282 TEST_F(WireReaderTest, InBoundFlowControl) {
283  ::testing::InSequence sequence;
284  UnblockSetupTransport();
285 
286  // data size
287  EXPECT_CALL(mock_readable_parcel_, GetDataSize).WillOnce(Return(1000));
288  // flag
289  ExpectReadInt32(kFlagMessageData | kFlagMessageDataIsPartial);
290  // sequence number
291  ExpectReadInt32(0);
292  // message size
293  ExpectReadInt32(1000);
294  EXPECT_CALL(mock_readable_parcel_, ReadByteArray)
295  .WillOnce(DoAll(SetArgPointee<0>(std::string(1000, 'a')),
296  Return(absl::OkStatus())));
297 
298  // Data is not completed. No callback will be triggered.
299  EXPECT_TRUE(CallProcessTransaction(kFirstCallId).ok());
300 
301  EXPECT_CALL(mock_readable_parcel_, GetDataSize).WillOnce(Return(1000));
302  // flag
303  ExpectReadInt32(kFlagMessageData);
304  // sequence number
305  ExpectReadInt32(1);
306  // message size
307  ExpectReadInt32(1000);
308  EXPECT_CALL(mock_readable_parcel_, ReadByteArray)
309  .WillOnce(DoAll(SetArgPointee<0>(std::string(1000, 'b')),
310  Return(absl::OkStatus())));
311 
313  NotifyRecvMessage(kFirstCallId,
314  StatusOrContainerEq(std::string(1000, 'a') +
315  std::string(1000, 'b'))));
316  EXPECT_TRUE(CallProcessTransaction(kFirstCallId).ok());
317 }
318 
319 TEST_F(WireReaderTest, ServerInitialMetadata) {
320  SetUp(/*is_client=*/false);
321 
322  ::testing::InSequence sequence;
323  UnblockSetupTransport();
324 
325  // flag
326  ExpectReadInt32(kFlagPrefix);
327  // sequence number
328  ExpectReadInt32(0);
329 
330  const std::vector<std::pair<std::string, std::string>> kMetadata = {
331  {"", ""},
332  {"", "value"},
333  {"key", ""},
334  {"key", "value"},
335  {"another-key", "another-value"},
336  };
337 
338  // method ref
339  ExpectReadString("test.service/rpc.method");
340 
341  // metadata
342  {
343  // count
344  ExpectReadInt32(kMetadata.size());
345  for (const auto& md : kMetadata) {
346  // metadata key
347  ExpectReadByteArray(md.first);
348  // metadata val
349  // TODO(waynetu): metadata value can also be "parcelable".
350  ExpectReadByteArray(md.second);
351  }
352  }
353 
354  // Since path and authority is not encoded as metadata in wire format,
355  // wire_reader implementation should insert them as metadata before passing
356  // to transport layer.
357  auto metadata_expectation = kMetadata;
358  metadata_expectation.push_back({":path", "/test.service/rpc.method"});
359  metadata_expectation.push_back({":authority", "binder.authority"});
360 
362  NotifyRecvInitialMetadata(
363  kFirstCallId, StatusOrContainerEq(metadata_expectation)));
364 
365  EXPECT_TRUE(CallProcessTransaction(kFirstCallId).ok());
366 }
367 
368 } // namespace grpc_binder
369 
370 int main(int argc, char** argv) {
371  ::testing::InitGoogleTest(&argc, argv);
372  grpc::testing::TestEnvironment env(&argc, argv);
373  return RUN_ALL_TESTS();
374 }
xds_interop_client.str
str
Definition: xds_interop_client.py:487
_gevent_test_main.result
result
Definition: _gevent_test_main.py:96
gen_build_yaml.out
dictionary out
Definition: src/benchmark/gen_build_yaml.py:24
generate.env
env
Definition: generate.py:37
grpc_binder::BinderTransportTxCode::PING_RESPONSE
@ PING_RESPONSE
grpc_binder::MockBinder::GetWriter
MockWritableParcel & GetWriter()
Definition: mock_objects.h:66
testing::Return
internal::ReturnAction< R > Return(R value)
Definition: bloaty/third_party/googletest/googlemock/include/gmock/gmock-actions.h:1004
grpc::experimental::binder::UntrustedSecurityPolicy
Definition: binder_security_policy.h:44
grpc_binder
Definition: connection_id_generator.cc:45
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
arg::value
void * value
Definition: cmdline.cc:44
transaction_code_t
uint32_t transaction_code_t
Definition: binder_constants.h:24
mock_objects.h
absl::OkStatus
Status OkStatus()
Definition: third_party/abseil-cpp/absl/status/status.h:882
grpc_binder::kFlagMessageDataIsPartial
const int kFlagMessageDataIsPartial
Definition: transaction.cc:30
tx_code
int tx_code
Definition: fake_binder_test.cc:241
wire_reader_
std::shared_ptr< WireReaderImpl > wire_reader_
Definition: wire_reader_test.cc:99
T
#define T(upbtypeconst, upbtype, ctype, default_value)
testing::Test
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:402
grpc_binder::kFlagStatusDescription
const int kFlagStatusDescription
Definition: transaction.cc:28
grpc_binder::MockReadableParcel
Definition: mock_objects.h:41
binder_security_policy.h
grpc_binder::MATCHER_P
MATCHER_P(StrEqInt8Ptr, target, "")
Definition: wire_writer_test.cc:33
absl::move
constexpr absl::remove_reference_t< T > && move(T &&t) noexcept
Definition: abseil-cpp/absl/utility/utility.h:221
transport_stream_receiver_
std::shared_ptr< StrictMock< MockTransportStreamReceiver > > transport_stream_receiver_
Definition: wire_reader_test.cc:98
wire_reader_impl.h
testing::InSequence
Definition: cares/cares/test/gmock-1.8.0/gmock/gmock.h:9838
testing::DoAll
internal::DoAllAction< typename std::decay< Action >::type... > DoAll(Action &&... action)
Definition: bloaty/third_party/googletest/googlemock/include/gmock/gmock-actions.h:964
arg
Definition: cmdline.cc:40
benchmark::Initialize
void Initialize(int *argc, char **argv)
Definition: benchmark/src/benchmark.cc:602
data
char data[kBufferLength]
Definition: abseil-cpp/absl/strings/internal/str_format/float_conversion.cc:1006
buffer
char buffer[1024]
Definition: libuv/docs/code/idle-compute/main.c:8
RUN_ALL_TESTS
int RUN_ALL_TESTS() GTEST_MUST_USE_RESULT_
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2471
grpc_binder::MockBinder
Definition: mock_objects.h:53
EXPECT_CALL
#define EXPECT_CALL(obj, call)
test_config.h
grpc_binder::kFlagPrefix
const int kFlagPrefix
Definition: transaction.cc:23
main
int main(int argc, char **argv)
Definition: wire_reader_test.cc:370
benchmark.md
md
Definition: benchmark.py:86
testing::InitGoogleTest
GTEST_API_ void InitGoogleTest(int *argc, char **argv)
Definition: bloaty/third_party/googletest/googletest/src/gtest.cc:6106
absl::Status
Definition: third_party/abseil-cpp/absl/status/status.h:424
grpc_binder::TEST_F
TEST_F(BinderTransportTest, CreateBinderTransport)
Definition: binder_transport_test.cc:363
grpc_binder::kFlagSuffix
const int kFlagSuffix
Definition: transaction.cc:25
grpc::testing::TestEnvironment
Definition: test/core/util/test_config.h:54
grpc_binder::kFlagMessageData
const int kFlagMessageData
Definition: transaction.cc:24
ok
bool ok
Definition: async_end2end_test.cc:197
EXPECT_TRUE
#define EXPECT_TRUE(condition)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1967
mock_readable_parcel_
MockReadableParcel mock_readable_parcel_
Definition: wire_reader_test.cc:100
grpc_binder::Metadata
std::vector< std::pair< std::string, std::string > > Metadata
Definition: transaction.h:38
grpc_binder::kFirstCallId
const int kFirstCallId
Definition: binder_constants.cc:26
testing::SetArgPointee
internal::SetArgumentPointeeAction< N, T > SetArgPointee(T x)
Definition: bloaty/third_party/googletest/googlemock/include/gmock/gmock-actions.h:1049
setup.target
target
Definition: third_party/bloaty/third_party/protobuf/python/setup.py:179


grpc
Author(s):
autogenerated on Thu Mar 13 2025 03:01:52