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
31 #include <grpc/grpc.h>
32 #include <grpcpp/security/binder_security_policy.h>
33
34 #include "src/core/ext/transport/binder/wire_format/wire_reader_impl.h"
35 #include "test/core/transport/binder/mock_objects.h"
36 #include "test/core/util/test_config.h"
37
38 namespace grpc_binder {
39
40 using ::testing::DoAll;
41 using ::testing::Return;
42 using ::testing::SetArgPointee;
43 using ::testing::StrictMock;
44
45 namespace {
46
47 class WireReaderTest : public ::testing::Test {
48 protected:
SetUp()49 void SetUp() override { SetUp(true); }
SetUp(bool is_client)50 void SetUp(bool is_client) {
51 transport_stream_receiver_ =
52 std::make_shared<StrictMock<MockTransportStreamReceiver>>();
53 wire_reader_ = std::make_shared<WireReaderImpl>(
54 transport_stream_receiver_, is_client,
55 std::make_shared<
56 grpc::experimental::binder::UntrustedSecurityPolicy>());
57 }
58
ExpectReadInt32(int result)59 void ExpectReadInt32(int result) {
60 EXPECT_CALL(mock_readable_parcel_, ReadInt32)
61 .WillOnce(DoAll(SetArgPointee<0>(result), Return(absl::OkStatus())));
62 }
63
ExpectReadByteArray(const std::string & buffer)64 void ExpectReadByteArray(const std::string& buffer) {
65 ExpectReadInt32(buffer.length());
66 if (!buffer.empty()) {
67 EXPECT_CALL(mock_readable_parcel_, ReadByteArray)
68 .WillOnce([buffer](std::string* data) {
69 *data = buffer;
70 return absl::OkStatus();
71 });
72 }
73 }
74
ExpectReadString(const std::string & str)75 void ExpectReadString(const std::string& str) {
76 EXPECT_CALL(mock_readable_parcel_, ReadString)
77 .WillOnce([str](std::string* out) {
78 *out = str;
79 return absl::OkStatus();
80 });
81 }
82
UnblockSetupTransport()83 void UnblockSetupTransport() {
84 // SETUP_TRANSPORT should finish before we can proceed with any other
85 // requests and streaming calls. The MockBinder will construct a
86 // MockTransactionReceiver, which will then sends SETUP_TRANSPORT request
87 // back to us.
88 wire_reader_->SetupTransport(std::make_unique<MockBinder>());
89 }
90
91 template <typename T>
CallProcessTransaction(T tx_code)92 absl::Status CallProcessTransaction(T tx_code) {
93 return wire_reader_->ProcessTransaction(
94 static_cast<transaction_code_t>(tx_code), &mock_readable_parcel_,
95 /*uid=*/0);
96 }
97
98 std::shared_ptr<StrictMock<MockTransportStreamReceiver>>
99 transport_stream_receiver_;
100 std::shared_ptr<WireReaderImpl> wire_reader_;
101 MockReadableParcel mock_readable_parcel_;
102 };
103
104 MATCHER_P(StatusOrStrEq, target, "") {
105 if (!arg.ok()) return false;
106 return arg.value() == target;
107 }
108
109 MATCHER_P(StatusOrContainerEq, target, "") {
110 if (!arg.ok()) return false;
111 return arg.value() == target;
112 }
113
114 } // namespace
115
TEST_F(WireReaderTest,SetupTransport)116 TEST_F(WireReaderTest, SetupTransport) {
117 auto mock_binder = std::make_unique<MockBinder>();
118 MockBinder& mock_binder_ref = *mock_binder;
119
120 ::testing::InSequence sequence;
121 EXPECT_CALL(mock_binder_ref, Initialize);
122 EXPECT_CALL(mock_binder_ref, PrepareTransaction);
123 const MockReadableParcel mock_readable_parcel;
124 EXPECT_CALL(mock_binder_ref, GetWritableParcel);
125
126 // Write version.
127 EXPECT_CALL(mock_binder_ref.GetWriter(), WriteInt32(1));
128
129 wire_reader_->SetupTransport(std::move(mock_binder));
130 }
131
TEST_F(WireReaderTest,ProcessTransactionControlMessageSetupTransport)132 TEST_F(WireReaderTest, ProcessTransactionControlMessageSetupTransport) {
133 ::testing::InSequence sequence;
134 UnblockSetupTransport();
135 }
136
TEST_F(WireReaderTest,ProcessTransactionControlMessagePingResponse)137 TEST_F(WireReaderTest, ProcessTransactionControlMessagePingResponse) {
138 ::testing::InSequence sequence;
139 UnblockSetupTransport();
140 EXPECT_CALL(mock_readable_parcel_, ReadInt32);
141 EXPECT_TRUE(
142 CallProcessTransaction(BinderTransportTxCode::PING_RESPONSE).ok());
143 }
144
TEST_F(WireReaderTest,ProcessTransactionServerRpcDataEmptyFlagIgnored)145 TEST_F(WireReaderTest, ProcessTransactionServerRpcDataEmptyFlagIgnored) {
146 ::testing::InSequence sequence;
147 UnblockSetupTransport();
148
149 // first transaction: empty flag
150 ExpectReadInt32(0);
151 // Won't further read sequence number.
152 EXPECT_TRUE(CallProcessTransaction(kFirstCallId).ok());
153 }
154
TEST_F(WireReaderTest,ProcessTransactionServerRpcDataFlagPrefixWithoutMetadata)155 TEST_F(WireReaderTest,
156 ProcessTransactionServerRpcDataFlagPrefixWithoutMetadata) {
157 ::testing::InSequence sequence;
158 UnblockSetupTransport();
159
160 // flag
161 ExpectReadInt32(kFlagPrefix);
162 // sequence number
163 ExpectReadInt32(0);
164
165 // count
166 ExpectReadInt32(0);
167 EXPECT_CALL(
168 *transport_stream_receiver_,
169 NotifyRecvInitialMetadata(kFirstCallId, StatusOrContainerEq(Metadata{})));
170
171 EXPECT_TRUE(CallProcessTransaction(kFirstCallId).ok());
172 }
173
TEST_F(WireReaderTest,ProcessTransactionServerRpcDataFlagPrefixWithMetadata)174 TEST_F(WireReaderTest, ProcessTransactionServerRpcDataFlagPrefixWithMetadata) {
175 ::testing::InSequence sequence;
176 UnblockSetupTransport();
177
178 // flag
179 ExpectReadInt32(kFlagPrefix);
180 // sequence number
181 ExpectReadInt32(0);
182
183 const std::vector<std::pair<std::string, std::string>> kMetadata = {
184 {"", ""},
185 {"", "value"},
186 {"key", ""},
187 {"key", "value"},
188 {"another-key", "another-value"},
189 };
190
191 // count
192 ExpectReadInt32(kMetadata.size());
193 for (const auto& md : kMetadata) {
194 // metadata key
195 ExpectReadByteArray(md.first);
196 // metadata val
197 // TODO(waynetu): metadata value can also be "parcelable".
198 ExpectReadByteArray(md.second);
199 }
200 EXPECT_CALL(
201 *transport_stream_receiver_,
202 NotifyRecvInitialMetadata(kFirstCallId, StatusOrContainerEq(kMetadata)));
203
204 EXPECT_TRUE(CallProcessTransaction(kFirstCallId).ok());
205 }
206
TEST_F(WireReaderTest,ProcessTransactionServerRpcDataFlagMessageDataNonEmpty)207 TEST_F(WireReaderTest, ProcessTransactionServerRpcDataFlagMessageDataNonEmpty) {
208 ::testing::InSequence sequence;
209 UnblockSetupTransport();
210
211 // flag
212 ExpectReadInt32(kFlagMessageData);
213 // sequence number
214 ExpectReadInt32(0);
215
216 // message data
217 // TODO(waynetu): message data can also be "parcelable".
218 const std::string kMessageData = "message data";
219 ExpectReadByteArray(kMessageData);
220 EXPECT_CALL(*transport_stream_receiver_,
221 NotifyRecvMessage(kFirstCallId, StatusOrStrEq(kMessageData)));
222
223 EXPECT_TRUE(CallProcessTransaction(kFirstCallId).ok());
224 }
225
TEST_F(WireReaderTest,ProcessTransactionServerRpcDataFlagMessageDataEmpty)226 TEST_F(WireReaderTest, ProcessTransactionServerRpcDataFlagMessageDataEmpty) {
227 ::testing::InSequence sequence;
228 UnblockSetupTransport();
229
230 // flag
231 ExpectReadInt32(kFlagMessageData);
232 // sequence number
233 ExpectReadInt32(0);
234
235 // message data
236 // TODO(waynetu): message data can also be "parcelable".
237 const std::string kMessageData;
238 ExpectReadByteArray(kMessageData);
239 EXPECT_CALL(*transport_stream_receiver_,
240 NotifyRecvMessage(kFirstCallId, StatusOrStrEq(kMessageData)));
241
242 EXPECT_TRUE(CallProcessTransaction(kFirstCallId).ok());
243 }
244
TEST_F(WireReaderTest,ProcessTransactionServerRpcDataFlagSuffixWithStatus)245 TEST_F(WireReaderTest, ProcessTransactionServerRpcDataFlagSuffixWithStatus) {
246 ::testing::InSequence sequence;
247 UnblockSetupTransport();
248
249 constexpr int kStatus = 0x1234;
250 // flag
251 ExpectReadInt32(kFlagSuffix | kFlagStatusDescription | (kStatus << 16));
252 // sequence number
253 ExpectReadInt32(0);
254 // status description
255 EXPECT_CALL(mock_readable_parcel_, ReadString);
256 // metadata count
257 ExpectReadInt32(0);
258 EXPECT_CALL(*transport_stream_receiver_,
259 NotifyRecvTrailingMetadata(
260 kFirstCallId, StatusOrContainerEq(Metadata{}), kStatus));
261
262 EXPECT_TRUE(CallProcessTransaction(kFirstCallId).ok());
263 }
264
TEST_F(WireReaderTest,ProcessTransactionServerRpcDataFlagSuffixWithoutStatus)265 TEST_F(WireReaderTest, ProcessTransactionServerRpcDataFlagSuffixWithoutStatus) {
266 ::testing::InSequence sequence;
267 UnblockSetupTransport();
268
269 // flag
270 ExpectReadInt32(kFlagSuffix);
271 // sequence number
272 ExpectReadInt32(0);
273 // No status description
274 // metadata count
275 ExpectReadInt32(0);
276 EXPECT_CALL(*transport_stream_receiver_,
277 NotifyRecvTrailingMetadata(kFirstCallId,
278 StatusOrContainerEq(Metadata{}), 0));
279
280 EXPECT_TRUE(CallProcessTransaction(kFirstCallId).ok());
281 }
282
TEST_F(WireReaderTest,InBoundFlowControl)283 TEST_F(WireReaderTest, InBoundFlowControl) {
284 ::testing::InSequence sequence;
285 UnblockSetupTransport();
286
287 // data size
288 EXPECT_CALL(mock_readable_parcel_, GetDataSize).WillOnce(Return(1000));
289 // flag
290 ExpectReadInt32(kFlagMessageData | kFlagMessageDataIsPartial);
291 // sequence number
292 ExpectReadInt32(0);
293 // message size
294 ExpectReadInt32(1000);
295 EXPECT_CALL(mock_readable_parcel_, ReadByteArray)
296 .WillOnce(DoAll(SetArgPointee<0>(std::string(1000, 'a')),
297 Return(absl::OkStatus())));
298
299 // Data is not completed. No callback will be triggered.
300 EXPECT_TRUE(CallProcessTransaction(kFirstCallId).ok());
301
302 EXPECT_CALL(mock_readable_parcel_, GetDataSize).WillOnce(Return(1000));
303 // flag
304 ExpectReadInt32(kFlagMessageData);
305 // sequence number
306 ExpectReadInt32(1);
307 // message size
308 ExpectReadInt32(1000);
309 EXPECT_CALL(mock_readable_parcel_, ReadByteArray)
310 .WillOnce(DoAll(SetArgPointee<0>(std::string(1000, 'b')),
311 Return(absl::OkStatus())));
312
313 EXPECT_CALL(*transport_stream_receiver_,
314 NotifyRecvMessage(kFirstCallId,
315 StatusOrContainerEq(std::string(1000, 'a') +
316 std::string(1000, 'b'))));
317 EXPECT_TRUE(CallProcessTransaction(kFirstCallId).ok());
318 }
319
TEST_F(WireReaderTest,ServerInitialMetadata)320 TEST_F(WireReaderTest, ServerInitialMetadata) {
321 SetUp(/*is_client=*/false);
322
323 ::testing::InSequence sequence;
324 UnblockSetupTransport();
325
326 // flag
327 ExpectReadInt32(kFlagPrefix);
328 // sequence number
329 ExpectReadInt32(0);
330
331 const std::vector<std::pair<std::string, std::string>> kMetadata = {
332 {"", ""},
333 {"", "value"},
334 {"key", ""},
335 {"key", "value"},
336 {"another-key", "another-value"},
337 };
338
339 // method ref
340 ExpectReadString("test.service/rpc.method");
341
342 // metadata
343 {
344 // count
345 ExpectReadInt32(kMetadata.size());
346 for (const auto& md : kMetadata) {
347 // metadata key
348 ExpectReadByteArray(md.first);
349 // metadata val
350 // TODO(waynetu): metadata value can also be "parcelable".
351 ExpectReadByteArray(md.second);
352 }
353 }
354
355 // Since path and authority is not encoded as metadata in wire format,
356 // wire_reader implementation should insert them as metadata before passing
357 // to transport layer.
358 auto metadata_expectation = kMetadata;
359 metadata_expectation.push_back({":path", "/test.service/rpc.method"});
360 metadata_expectation.push_back({":authority", "binder.authority"});
361
362 EXPECT_CALL(*transport_stream_receiver_,
363 NotifyRecvInitialMetadata(
364 kFirstCallId, StatusOrContainerEq(metadata_expectation)));
365
366 EXPECT_TRUE(CallProcessTransaction(kFirstCallId).ok());
367 }
368
369 } // namespace grpc_binder
370
main(int argc,char ** argv)371 int main(int argc, char** argv) {
372 ::testing::InitGoogleTest(&argc, argv);
373 grpc::testing::TestEnvironment env(&argc, argv);
374 grpc_init();
375 auto results = RUN_ALL_TESTS();
376 grpc_shutdown();
377 return results;
378 }
379