1 // Copyright 2021 gRPC authors.
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
7 // http://www.apache.org/licenses/LICENSE-2.0
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.
15 // Unit tests for WireReaderImpl.
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.
26 #include <gtest/gtest.h>
28 #include "absl/memory/memory.h"
30 #include "src/core/ext/transport/binder/wire_format/wire_reader_impl.h"
31 #include "test/core/transport/binder/mock_objects.h"
32 #include "test/core/util/test_config.h"
34 namespace grpc_binder {
36 using ::testing::DoAll;
37 using ::testing::Return;
38 using ::testing::SetArgPointee;
39 using ::testing::StrictMock;
43 class WireReaderTest : public ::testing::Test {
46 : transport_stream_receiver_(
47 std::make_shared<StrictMock<MockTransportStreamReceiver>>()),
48 wire_reader_(transport_stream_receiver_, /*is_client=*/true) {}
51 void ExpectReadInt32(int result) {
52 EXPECT_CALL(mock_readable_parcel_, ReadInt32)
53 .WillOnce(DoAll(SetArgPointee<0>(result), Return(absl::OkStatus())));
56 void ExpectReadByteArray(const std::string& buffer) {
57 ExpectReadInt32(buffer.length());
58 if (!buffer.empty()) {
59 EXPECT_CALL(mock_readable_parcel_, ReadByteArray)
60 .WillOnce([buffer](std::string* data) {
62 return absl::OkStatus();
67 void UnblockSetupTransport() {
68 // SETUP_TRANSPORT should finish before we can proceed with any other
69 // requests and streaming calls. The MockBinder will construct a
70 // MockTransactionReceiver, which will then sends SETUP_TRANSPORT request
72 wire_reader_.SetupTransport(absl::make_unique<MockBinder>());
76 absl::Status CallProcessTransaction(T tx_code) {
77 return wire_reader_.ProcessTransaction(
78 static_cast<transaction_code_t>(tx_code), &mock_readable_parcel_);
81 std::shared_ptr<StrictMock<MockTransportStreamReceiver>>
82 transport_stream_receiver_;
83 WireReaderImpl wire_reader_;
84 MockReadableParcel mock_readable_parcel_;
87 MATCHER_P(StatusOrStrEq, target, "") {
88 if (!arg.ok()) return false;
89 return arg.value() == target;
92 MATCHER_P(StatusOrContainerEq, target, "") {
93 if (!arg.ok()) return false;
94 return arg.value() == target;
99 TEST_F(WireReaderTest, SetupTransport) {
100 auto mock_binder = absl::make_unique<MockBinder>();
101 MockBinder& mock_binder_ref = *mock_binder;
103 ::testing::InSequence sequence;
104 EXPECT_CALL(mock_binder_ref, Initialize);
105 EXPECT_CALL(mock_binder_ref, PrepareTransaction);
106 const MockReadableParcel mock_readable_parcel;
107 EXPECT_CALL(mock_binder_ref, GetWritableParcel);
110 EXPECT_CALL(mock_binder_ref.GetWriter(), WriteInt32(77));
112 // The transaction receiver immediately informs the wire writer that the
113 // transport has been successfully set up.
114 EXPECT_CALL(mock_binder_ref, ConstructTxReceiver);
116 EXPECT_CALL(mock_binder_ref.GetReader(), ReadInt32);
117 EXPECT_CALL(mock_binder_ref.GetReader(), ReadBinder);
119 // Write transaction receiver.
120 EXPECT_CALL(mock_binder_ref.GetWriter(), WriteBinder);
121 // Perform transaction.
122 EXPECT_CALL(mock_binder_ref, Transact);
124 wire_reader_.SetupTransport(std::move(mock_binder));
127 TEST_F(WireReaderTest, ProcessTransactionControlMessageSetupTransport) {
128 ::testing::InSequence sequence;
129 UnblockSetupTransport();
132 TEST_F(WireReaderTest, ProcessTransactionControlMessagePingResponse) {
133 ::testing::InSequence sequence;
134 UnblockSetupTransport();
135 EXPECT_CALL(mock_readable_parcel_, ReadInt32);
137 CallProcessTransaction(BinderTransportTxCode::PING_RESPONSE).ok());
140 TEST_F(WireReaderTest, ProcessTransactionServerRpcDataEmptyFlagIgnored) {
141 ::testing::InSequence sequence;
142 UnblockSetupTransport();
144 // first transaction: empty flag
146 // Won't further read sequence number.
147 EXPECT_TRUE(CallProcessTransaction(kFirstCallId).ok());
150 TEST_F(WireReaderTest,
151 ProcessTransactionServerRpcDataFlagPrefixWithoutMetadata) {
152 ::testing::InSequence sequence;
153 UnblockSetupTransport();
156 ExpectReadInt32(kFlagPrefix);
163 *transport_stream_receiver_,
164 NotifyRecvInitialMetadata(kFirstCallId, StatusOrContainerEq(Metadata{})));
166 EXPECT_TRUE(CallProcessTransaction(kFirstCallId).ok());
169 TEST_F(WireReaderTest, ProcessTransactionServerRpcDataFlagPrefixWithMetadata) {
170 ::testing::InSequence sequence;
171 UnblockSetupTransport();
174 ExpectReadInt32(kFlagPrefix);
178 const std::vector<std::pair<std::string, std::string>> kMetadata = {
183 {"another-key", "another-value"},
187 ExpectReadInt32(kMetadata.size());
188 for (const auto& md : kMetadata) {
190 ExpectReadByteArray(md.first);
192 // TODO(waynetu): metadata value can also be "parcelable".
193 ExpectReadByteArray(md.second);
196 *transport_stream_receiver_,
197 NotifyRecvInitialMetadata(kFirstCallId, StatusOrContainerEq(kMetadata)));
199 EXPECT_TRUE(CallProcessTransaction(kFirstCallId).ok());
202 TEST_F(WireReaderTest, ProcessTransactionServerRpcDataFlagMessageDataNonEmpty) {
203 ::testing::InSequence sequence;
204 UnblockSetupTransport();
207 ExpectReadInt32(kFlagMessageData);
212 // TODO(waynetu): message data can also be "parcelable".
213 const std::string kMessageData = "message data";
214 ExpectReadByteArray(kMessageData);
215 EXPECT_CALL(*transport_stream_receiver_,
216 NotifyRecvMessage(kFirstCallId, StatusOrStrEq(kMessageData)));
218 EXPECT_TRUE(CallProcessTransaction(kFirstCallId).ok());
221 TEST_F(WireReaderTest, ProcessTransactionServerRpcDataFlagMessageDataEmpty) {
222 ::testing::InSequence sequence;
223 UnblockSetupTransport();
226 ExpectReadInt32(kFlagMessageData);
231 // TODO(waynetu): message data can also be "parcelable".
232 const std::string kMessageData = "";
233 ExpectReadByteArray(kMessageData);
234 EXPECT_CALL(*transport_stream_receiver_,
235 NotifyRecvMessage(kFirstCallId, StatusOrStrEq(kMessageData)));
237 EXPECT_TRUE(CallProcessTransaction(kFirstCallId).ok());
240 TEST_F(WireReaderTest, ProcessTransactionServerRpcDataFlagSuffixWithStatus) {
241 ::testing::InSequence sequence;
242 UnblockSetupTransport();
244 constexpr int kStatus = 0x1234;
246 ExpectReadInt32(kFlagSuffix | kFlagStatusDescription | (kStatus << 16));
249 // status description
250 EXPECT_CALL(mock_readable_parcel_, ReadString);
253 EXPECT_CALL(*transport_stream_receiver_,
254 NotifyRecvTrailingMetadata(
255 kFirstCallId, StatusOrContainerEq(Metadata{}), kStatus));
257 EXPECT_TRUE(CallProcessTransaction(kFirstCallId).ok());
260 TEST_F(WireReaderTest, ProcessTransactionServerRpcDataFlagSuffixWithoutStatus) {
261 ::testing::InSequence sequence;
262 UnblockSetupTransport();
265 ExpectReadInt32(kFlagSuffix);
268 // No status description
271 EXPECT_CALL(*transport_stream_receiver_,
272 NotifyRecvTrailingMetadata(kFirstCallId,
273 StatusOrContainerEq(Metadata{}), 0));
275 EXPECT_TRUE(CallProcessTransaction(kFirstCallId).ok());
278 TEST_F(WireReaderTest, InBoundFlowControl) {
279 ::testing::InSequence sequence;
280 UnblockSetupTransport();
283 EXPECT_CALL(mock_readable_parcel_, GetDataSize).WillOnce(Return(1000));
285 ExpectReadInt32(kFlagMessageData | kFlagMessageDataIsPartial);
289 ExpectReadInt32(1000);
290 EXPECT_CALL(mock_readable_parcel_, ReadByteArray)
291 .WillOnce(DoAll(SetArgPointee<0>(std::string(1000, 'a')),
292 Return(absl::OkStatus())));
294 // Data is not completed. No callback will be triggered.
295 EXPECT_TRUE(CallProcessTransaction(kFirstCallId).ok());
297 EXPECT_CALL(mock_readable_parcel_, GetDataSize).WillOnce(Return(1000));
299 ExpectReadInt32(kFlagMessageData);
303 ExpectReadInt32(1000);
304 EXPECT_CALL(mock_readable_parcel_, ReadByteArray)
305 .WillOnce(DoAll(SetArgPointee<0>(std::string(1000, 'b')),
306 Return(absl::OkStatus())));
308 EXPECT_CALL(*transport_stream_receiver_,
309 NotifyRecvMessage(kFirstCallId,
310 StatusOrContainerEq(std::string(1000, 'a') +
311 std::string(1000, 'b'))));
312 EXPECT_TRUE(CallProcessTransaction(kFirstCallId).ok());
315 } // namespace grpc_binder
317 int main(int argc, char** argv) {
318 ::testing::InitGoogleTest(&argc, argv);
319 grpc::testing::TestEnvironment env(argc, argv);
320 return RUN_ALL_TESTS();