xref: /aosp_15_r20/external/grpc-grpc/test/core/transport/binder/binder_transport_test.cc (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
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 grpc_binder_transport
16 //
17 // Verify that a calls to the perform_stream_op of grpc_binder_transport
18 // transform into the correct sequence of binder transactions.
19 #include "src/core/ext/transport/binder/transport/binder_transport.h"
20 
21 #include <memory>
22 #include <string>
23 #include <vector>
24 
25 #include <gtest/gtest.h>
26 
27 #include "absl/memory/memory.h"
28 #include "absl/strings/match.h"
29 #include "absl/strings/str_join.h"
30 
31 #include <grpc/grpc.h>
32 #include <grpcpp/security/binder_security_policy.h>
33 
34 #include "src/core/ext/transport/binder/transport/binder_stream.h"
35 #include "src/core/lib/gprpp/notification.h"
36 #include "src/core/lib/resource_quota/resource_quota.h"
37 #include "test/core/transport/binder/mock_objects.h"
38 #include "test/core/util/test_config.h"
39 
40 namespace grpc_binder {
41 namespace {
42 
43 using ::testing::Expectation;
44 using ::testing::NiceMock;
45 using ::testing::Return;
46 
47 class BinderTransportTest : public ::testing::Test {
48  public:
BinderTransportTest()49   BinderTransportTest()
50       : transport_(grpc_create_binder_transport_client(
51             std::make_unique<NiceMock<MockBinder>>(),
52             std::make_shared<
53                 grpc::experimental::binder::UntrustedSecurityPolicy>())) {
54     auto* gbt = reinterpret_cast<grpc_binder_transport*>(transport_);
55     gbt->wire_writer = std::make_unique<MockWireWriter>();
56     GRPC_STREAM_REF_INIT(&ref_, 1, nullptr, nullptr, "phony ref");
57   }
58 
~BinderTransportTest()59   ~BinderTransportTest() override {
60     grpc_core::ExecCtx exec_ctx;
61     transport_->Orphan();
62     grpc_core::ExecCtx::Get()->Flush();
63     for (grpc_binder_stream* gbs : stream_buffer_) {
64       gbs->~grpc_binder_stream();
65       gpr_free(gbs);
66     }
67     arena_->Destroy();
68   }
69 
PerformStreamOp(grpc_binder_stream * gbs,grpc_transport_stream_op_batch * op)70   void PerformStreamOp(grpc_binder_stream* gbs,
71                        grpc_transport_stream_op_batch* op) {
72     transport_->filter_stack_transport()->PerformStreamOp(
73         reinterpret_cast<grpc_stream*>(gbs), op);
74   }
75 
GetBinderTransport()76   grpc_binder_transport* GetBinderTransport() {
77     return reinterpret_cast<grpc_binder_transport*>(transport_);
78   }
79 
InitNewBinderStream()80   grpc_binder_stream* InitNewBinderStream() {
81     grpc_binder_stream* gbs = static_cast<grpc_binder_stream*>(
82         gpr_malloc(transport_->filter_stack_transport()->SizeOfStream()));
83     transport_->filter_stack_transport()->InitStream(
84         reinterpret_cast<grpc_stream*>(gbs), &ref_, nullptr, arena_);
85     stream_buffer_.push_back(gbs);
86     return gbs;
87   }
88 
GetWireWriter()89   MockWireWriter& GetWireWriter() {
90     return *reinterpret_cast<MockWireWriter*>(
91         GetBinderTransport()->wire_writer.get());
92   }
93 
SetUpTestSuite()94   static void SetUpTestSuite() { grpc_init(); }
TearDownTestSuite()95   static void TearDownTestSuite() { grpc_shutdown(); }
96 
97  protected:
98   grpc_core::MemoryAllocator memory_allocator_ =
99       grpc_core::MemoryAllocator(grpc_core::ResourceQuota::Default()
100                                      ->memory_quota()
101                                      ->CreateMemoryAllocator("test"));
102   grpc_core::Arena* arena_ =
103       grpc_core::Arena::Create(/* initial_size = */ 1, &memory_allocator_);
104   grpc_core::Transport* transport_;
105   grpc_stream_refcount ref_;
106   std::vector<grpc_binder_stream*> stream_buffer_;
107 };
108 
109 void MockCallback(void* arg, grpc_error_handle error);
110 
111 class MockGrpcClosure {
112  public:
MockGrpcClosure(grpc_core::Notification * notification=nullptr)113   explicit MockGrpcClosure(grpc_core::Notification* notification = nullptr)
114       : notification_(notification) {
115     GRPC_CLOSURE_INIT(&closure_, MockCallback, this, nullptr);
116   }
117 
GetGrpcClosure()118   grpc_closure* GetGrpcClosure() { return &closure_; }
119   MOCK_METHOD(void, Callback, (grpc_error_handle), ());
120 
121   grpc_core::Notification* notification_;
122 
123  private:
124   grpc_closure closure_;
125 };
126 
MockCallback(void * arg,grpc_error_handle error)127 void MockCallback(void* arg, grpc_error_handle error) {
128   MockGrpcClosure* mock_closure = static_cast<MockGrpcClosure*>(arg);
129   mock_closure->Callback(error);
130   if (mock_closure->notification_) {
131     mock_closure->notification_->Notify();
132   }
133 }
134 
MetadataString(const Metadata & a)135 std::string MetadataString(const Metadata& a) {
136   return absl::StrCat(
137       "{",
138       absl::StrJoin(
139           a, ", ",
140           [](std::string* out, const std::pair<std::string, std::string>& kv) {
141             out->append(
142                 absl::StrCat("\"", kv.first, "\": \"", kv.second, "\""));
143           }),
144       "}");
145 }
146 
MetadataEquivalent(Metadata a,Metadata b)147 bool MetadataEquivalent(Metadata a, Metadata b) {
148   std::sort(a.begin(), a.end());
149   std::sort(b.begin(), b.end());
150   return a == b;
151 }
152 
153 // Matches with transactions having the desired flag, method_ref,
154 // initial_metadata, and message_data.
155 MATCHER_P4(TransactionMatches, flag, method_ref, initial_metadata, message_data,
156            "") {
157   if (arg->GetFlags() != flag) return false;
158   if (flag & kFlagPrefix) {
159     if (arg->GetMethodRef() != method_ref) {
160       printf("METHOD REF NOT EQ: %s %s\n",
161              std::string(arg->GetMethodRef()).c_str(),
162              std::string(method_ref).c_str());
163       return false;
164     }
165     if (!MetadataEquivalent(arg->GetPrefixMetadata(), initial_metadata)) {
166       printf("METADATA NOT EQUIVALENT: %s %s\n",
167              MetadataString(arg->GetPrefixMetadata()).c_str(),
168              MetadataString(initial_metadata).c_str());
169       return false;
170     }
171   }
172   if (flag & kFlagMessageData) {
173     if (arg->GetMessageData() != message_data) return false;
174   }
175   return true;
176 }
177 
178 // Matches with grpc_error having error message containing |msg|.
179 MATCHER_P(GrpcErrorMessageContains, msg, "") {
180   return absl::StrContains(grpc_core::StatusToString(arg), msg);
181 }
182 
183 namespace {
184 class MetadataEncoder {
185  public:
Encode(const grpc_core::Slice & key,const grpc_core::Slice & value)186   void Encode(const grpc_core::Slice& key, const grpc_core::Slice& value) {
187     metadata_.emplace_back(std::string(key.as_string_view()),
188                            std::string(value.as_string_view()));
189   }
190 
191   template <typename Which>
Encode(Which,const typename Which::ValueType & value)192   void Encode(Which, const typename Which::ValueType& value) {
193     metadata_.emplace_back(
194         std::string(Which::key()),
195         // NOLINTNEXTLINE(google-readability-casting)
196         std::string(grpc_core::Slice(Which::Encode(value)).as_string_view()));
197   }
198 
metadata() const199   const Metadata& metadata() const { return metadata_; }
200 
201  private:
202   Metadata metadata_;
203 };
204 }  // namespace
205 
206 // Verify that the lower-level metadata has the same content as the gRPC
207 // metadata.
VerifyMetadataEqual(const Metadata & md,const grpc_metadata_batch & grpc_md)208 void VerifyMetadataEqual(const Metadata& md,
209                          const grpc_metadata_batch& grpc_md) {
210   MetadataEncoder encoder;
211   grpc_md.Encode(&encoder);
212   EXPECT_TRUE(MetadataEquivalent(encoder.metadata(), md));
213 }
214 
215 // RAII helper classes for constructing gRPC metadata and receiving callbacks.
216 struct MakeSendInitialMetadata {
MakeSendInitialMetadatagrpc_binder::__anon521925940111::MakeSendInitialMetadata217   MakeSendInitialMetadata(const Metadata& initial_metadata,
218                           const std::string& method_ref,
219                           grpc_transport_stream_op_batch* op) {
220     for (const auto& md : initial_metadata) {
221       const std::string& key = md.first;
222       const std::string& value = md.second;
223       grpc_initial_metadata.Append(
224           key, grpc_core::Slice::FromCopiedString(value),
225           [](absl::string_view, const grpc_core::Slice&) { abort(); });
226     }
227     if (!method_ref.empty()) {
228       grpc_initial_metadata.Set(grpc_core::HttpPathMetadata(),
229                                 grpc_core::Slice::FromCopiedString(method_ref));
230     }
231     op->send_initial_metadata = true;
232     op->payload->send_initial_metadata.send_initial_metadata =
233         &grpc_initial_metadata;
234   }
~MakeSendInitialMetadatagrpc_binder::__anon521925940111::MakeSendInitialMetadata235   ~MakeSendInitialMetadata() {}
236 
237   grpc_core::MemoryAllocator memory_allocator =
238       grpc_core::MemoryAllocator(grpc_core::ResourceQuota::Default()
239                                      ->memory_quota()
240                                      ->CreateMemoryAllocator("test"));
241   grpc_core::ScopedArenaPtr arena =
242       grpc_core::MakeScopedArena(1024, &memory_allocator);
243   grpc_metadata_batch grpc_initial_metadata;
244 };
245 
246 struct MakeSendMessage {
MakeSendMessagegrpc_binder::__anon521925940111::MakeSendMessage247   MakeSendMessage(const std::string& message,
248                   grpc_transport_stream_op_batch* op) {
249     send_stream.Append(grpc_core::Slice::FromCopiedString(message));
250 
251     op->send_message = true;
252     op->payload->send_message.send_message = &send_stream;
253   }
254 
255   grpc_core::SliceBuffer send_stream;
256 };
257 
258 struct MakeSendTrailingMetadata {
MakeSendTrailingMetadatagrpc_binder::__anon521925940111::MakeSendTrailingMetadata259   explicit MakeSendTrailingMetadata(const Metadata& trailing_metadata,
260                                     grpc_transport_stream_op_batch* op) {
261     EXPECT_TRUE(trailing_metadata.empty());
262 
263     op->send_trailing_metadata = true;
264     op->payload->send_trailing_metadata.send_trailing_metadata =
265         &grpc_trailing_metadata;
266   }
267 
268   grpc_core::MemoryAllocator memory_allocator =
269       grpc_core::MemoryAllocator(grpc_core::ResourceQuota::Default()
270                                      ->memory_quota()
271                                      ->CreateMemoryAllocator("test"));
272   grpc_core::ScopedArenaPtr arena =
273       grpc_core::MakeScopedArena(1024, &memory_allocator);
274   grpc_metadata_batch grpc_trailing_metadata;
275 };
276 
277 struct MakeRecvInitialMetadata {
MakeRecvInitialMetadatagrpc_binder::__anon521925940111::MakeRecvInitialMetadata278   explicit MakeRecvInitialMetadata(grpc_transport_stream_op_batch* op,
279                                    Expectation* call_before = nullptr)
280       : ready(&notification) {
281     op->recv_initial_metadata = true;
282     op->payload->recv_initial_metadata.recv_initial_metadata =
283         &grpc_initial_metadata;
284     op->payload->recv_initial_metadata.recv_initial_metadata_ready =
285         ready.GetGrpcClosure();
286     if (call_before) {
287       EXPECT_CALL(ready, Callback).After(*call_before);
288     } else {
289       EXPECT_CALL(ready, Callback);
290     }
291   }
292 
~MakeRecvInitialMetadatagrpc_binder::__anon521925940111::MakeRecvInitialMetadata293   ~MakeRecvInitialMetadata() {}
294 
295   MockGrpcClosure ready;
296   grpc_core::MemoryAllocator memory_allocator =
297       grpc_core::MemoryAllocator(grpc_core::ResourceQuota::Default()
298                                      ->memory_quota()
299                                      ->CreateMemoryAllocator("test"));
300   grpc_core::ScopedArenaPtr arena =
301       grpc_core::MakeScopedArena(1024, &memory_allocator);
302   grpc_metadata_batch grpc_initial_metadata;
303   grpc_core::Notification notification;
304 };
305 
306 struct MakeRecvMessage {
MakeRecvMessagegrpc_binder::__anon521925940111::MakeRecvMessage307   explicit MakeRecvMessage(grpc_transport_stream_op_batch* op,
308                            Expectation* call_before = nullptr)
309       : ready(&notification) {
310     op->recv_message = true;
311     op->payload->recv_message.recv_message = &grpc_message;
312     op->payload->recv_message.recv_message_ready = ready.GetGrpcClosure();
313     if (call_before) {
314       EXPECT_CALL(ready, Callback).After(*call_before);
315     } else {
316       EXPECT_CALL(ready, Callback);
317     }
318   }
319 
320   MockGrpcClosure ready;
321   grpc_core::Notification notification;
322   absl::optional<grpc_core::SliceBuffer> grpc_message;
323 };
324 
325 struct MakeRecvTrailingMetadata {
MakeRecvTrailingMetadatagrpc_binder::__anon521925940111::MakeRecvTrailingMetadata326   explicit MakeRecvTrailingMetadata(grpc_transport_stream_op_batch* op,
327                                     Expectation* call_before = nullptr)
328       : ready(&notification) {
329     op->recv_trailing_metadata = true;
330     op->payload->recv_trailing_metadata.recv_trailing_metadata =
331         &grpc_trailing_metadata;
332     op->payload->recv_trailing_metadata.recv_trailing_metadata_ready =
333         ready.GetGrpcClosure();
334     if (call_before) {
335       EXPECT_CALL(ready, Callback).After(*call_before);
336     } else {
337       EXPECT_CALL(ready, Callback);
338     }
339   }
340 
~MakeRecvTrailingMetadatagrpc_binder::__anon521925940111::MakeRecvTrailingMetadata341   ~MakeRecvTrailingMetadata() {}
342 
343   MockGrpcClosure ready;
344   grpc_core::MemoryAllocator memory_allocator =
345       grpc_core::MemoryAllocator(grpc_core::ResourceQuota::Default()
346                                      ->memory_quota()
347                                      ->CreateMemoryAllocator("test"));
348   grpc_core::ScopedArenaPtr arena =
349       grpc_core::MakeScopedArena(1024, &memory_allocator);
350   grpc_metadata_batch grpc_trailing_metadata;
351   grpc_core::Notification notification;
352 };
353 
354 const Metadata kDefaultMetadata = {
355     {"", ""},
356     {"", "value"},
357     {"key", ""},
358     {"key", "value"},
359 };
360 
361 constexpr char kDefaultMethodRef[] = "/some/path";
362 constexpr char kDefaultMessage[] = "binder transport message";
363 constexpr int kDefaultStatus = 0x1234;
364 
AppendMethodRef(const Metadata & md,const std::string & method_ref)365 Metadata AppendMethodRef(const Metadata& md, const std::string& method_ref) {
366   Metadata result = md;
367   result.emplace_back(":path", method_ref);
368   return result;
369 }
370 
AppendStatus(const Metadata & md,int status)371 Metadata AppendStatus(const Metadata& md, int status) {
372   Metadata result = md;
373   result.emplace_back("grpc-status", std::to_string(status));
374   return result;
375 }
376 
377 }  // namespace
378 
TEST_F(BinderTransportTest,CreateBinderTransport)379 TEST_F(BinderTransportTest, CreateBinderTransport) {
380   EXPECT_NE(transport_, nullptr);
381 }
382 
TEST_F(BinderTransportTest,TransactionIdIncrement)383 TEST_F(BinderTransportTest, TransactionIdIncrement) {
384   grpc_binder_stream* gbs0 = InitNewBinderStream();
385   EXPECT_EQ(gbs0->t, GetBinderTransport());
386   EXPECT_EQ(gbs0->tx_code, kFirstCallId);
387   grpc_binder_stream* gbs1 = InitNewBinderStream();
388   EXPECT_EQ(gbs1->t, GetBinderTransport());
389   EXPECT_EQ(gbs1->tx_code, kFirstCallId + 1);
390   grpc_binder_stream* gbs2 = InitNewBinderStream();
391   EXPECT_EQ(gbs2->t, GetBinderTransport());
392   EXPECT_EQ(gbs2->tx_code, kFirstCallId + 2);
393 }
394 
TEST_F(BinderTransportTest,PerformSendInitialMetadata)395 TEST_F(BinderTransportTest, PerformSendInitialMetadata) {
396   grpc_core::ExecCtx exec_ctx;
397   grpc_binder_stream* gbs = InitNewBinderStream();
398   grpc_transport_stream_op_batch op{};
399   grpc_transport_stream_op_batch_payload payload(nullptr);
400   op.payload = &payload;
401   const Metadata kInitialMetadata = kDefaultMetadata;
402   MakeSendInitialMetadata send_initial_metadata(kInitialMetadata, "", &op);
403   MockGrpcClosure mock_on_complete;
404   op.on_complete = mock_on_complete.GetGrpcClosure();
405 
406   ::testing::InSequence sequence;
407   EXPECT_CALL(GetWireWriter(), RpcCall(TransactionMatches(
408                                    kFlagPrefix, "", kInitialMetadata, "")));
409   EXPECT_CALL(mock_on_complete, Callback);
410 
411   PerformStreamOp(gbs, &op);
412   grpc_core::ExecCtx::Get()->Flush();
413 }
414 
TEST_F(BinderTransportTest,PerformSendInitialMetadataMethodRef)415 TEST_F(BinderTransportTest, PerformSendInitialMetadataMethodRef) {
416   grpc_core::ExecCtx exec_ctx;
417   grpc_binder_stream* gbs = InitNewBinderStream();
418   grpc_transport_stream_op_batch op{};
419   grpc_transport_stream_op_batch_payload payload(nullptr);
420   op.payload = &payload;
421   const Metadata kInitialMetadata = kDefaultMetadata;
422   const std::string kMethodRef = kDefaultMethodRef;
423   MakeSendInitialMetadata send_initial_metadata(kInitialMetadata, kMethodRef,
424                                                 &op);
425   MockGrpcClosure mock_on_complete;
426   op.on_complete = mock_on_complete.GetGrpcClosure();
427 
428   ::testing::InSequence sequence;
429   EXPECT_CALL(GetWireWriter(),
430               RpcCall(TransactionMatches(kFlagPrefix, kMethodRef.substr(1),
431                                          kInitialMetadata, "")));
432   EXPECT_CALL(mock_on_complete, Callback);
433 
434   PerformStreamOp(gbs, &op);
435   grpc_core::ExecCtx::Get()->Flush();
436 }
437 
TEST_F(BinderTransportTest,PerformSendMessage)438 TEST_F(BinderTransportTest, PerformSendMessage) {
439   grpc_core::ExecCtx exec_ctx;
440   grpc_binder_stream* gbs = InitNewBinderStream();
441   grpc_transport_stream_op_batch op{};
442   grpc_transport_stream_op_batch_payload payload(nullptr);
443   op.payload = &payload;
444 
445   const std::string kMessage = kDefaultMessage;
446   MakeSendMessage send_message(kMessage, &op);
447   MockGrpcClosure mock_on_complete;
448   op.on_complete = mock_on_complete.GetGrpcClosure();
449 
450   ::testing::InSequence sequence;
451   EXPECT_CALL(
452       GetWireWriter(),
453       RpcCall(TransactionMatches(kFlagMessageData, "", Metadata{}, kMessage)));
454   EXPECT_CALL(mock_on_complete, Callback);
455 
456   PerformStreamOp(gbs, &op);
457   grpc_core::ExecCtx::Get()->Flush();
458 }
459 
TEST_F(BinderTransportTest,PerformSendTrailingMetadata)460 TEST_F(BinderTransportTest, PerformSendTrailingMetadata) {
461   grpc_core::ExecCtx exec_ctx;
462   grpc_binder_stream* gbs = InitNewBinderStream();
463   grpc_transport_stream_op_batch op{};
464   grpc_transport_stream_op_batch_payload payload(nullptr);
465   op.payload = &payload;
466   // The wireformat guarantees that suffix metadata will always be empty.
467   // TODO(waynetu): Check whether gRPC can internally add extra trailing
468   // metadata.
469   const Metadata kTrailingMetadata = {};
470   MakeSendTrailingMetadata send_trailing_metadata(kTrailingMetadata, &op);
471   MockGrpcClosure mock_on_complete;
472   op.on_complete = mock_on_complete.GetGrpcClosure();
473 
474   ::testing::InSequence sequence;
475   EXPECT_CALL(GetWireWriter(), RpcCall(TransactionMatches(
476                                    kFlagSuffix, "", kTrailingMetadata, "")));
477   EXPECT_CALL(mock_on_complete, Callback);
478 
479   PerformStreamOp(gbs, &op);
480   grpc_core::ExecCtx::Get()->Flush();
481 }
482 
TEST_F(BinderTransportTest,PerformSendAll)483 TEST_F(BinderTransportTest, PerformSendAll) {
484   grpc_core::ExecCtx exec_ctx;
485   grpc_binder_stream* gbs = InitNewBinderStream();
486   grpc_transport_stream_op_batch op{};
487   grpc_transport_stream_op_batch_payload payload(nullptr);
488   op.payload = &payload;
489 
490   const Metadata kInitialMetadata = kDefaultMetadata;
491   const std::string kMethodRef = kDefaultMethodRef;
492   MakeSendInitialMetadata send_initial_metadata(kInitialMetadata, kMethodRef,
493                                                 &op);
494 
495   const std::string kMessage = kDefaultMessage;
496   MakeSendMessage send_message(kMessage, &op);
497 
498   // The wireformat guarantees that suffix metadata will always be empty.
499   // TODO(waynetu): Check whether gRPC can internally add extra trailing
500   // metadata.
501   const Metadata kTrailingMetadata = {};
502   MakeSendTrailingMetadata send_trailing_metadata(kTrailingMetadata, &op);
503 
504   MockGrpcClosure mock_on_complete;
505   op.on_complete = mock_on_complete.GetGrpcClosure();
506 
507   ::testing::InSequence sequence;
508   EXPECT_CALL(GetWireWriter(),
509               RpcCall(TransactionMatches(
510                   kFlagPrefix | kFlagMessageData | kFlagSuffix,
511                   kMethodRef.substr(1), kInitialMetadata, kMessage)));
512   EXPECT_CALL(mock_on_complete, Callback);
513 
514   PerformStreamOp(gbs, &op);
515   grpc_core::ExecCtx::Get()->Flush();
516 }
517 
TEST_F(BinderTransportTest,PerformRecvInitialMetadata)518 TEST_F(BinderTransportTest, PerformRecvInitialMetadata) {
519   grpc_core::ExecCtx exec_ctx;
520   grpc_binder_stream* gbs = InitNewBinderStream();
521   grpc_transport_stream_op_batch op{};
522   grpc_transport_stream_op_batch_payload payload(nullptr);
523   op.payload = &payload;
524 
525   MakeRecvInitialMetadata recv_initial_metadata(&op);
526 
527   const Metadata kInitialMetadata = kDefaultMetadata;
528   auto* gbt = reinterpret_cast<grpc_binder_transport*>(transport_);
529   gbt->transport_stream_receiver->NotifyRecvInitialMetadata(gbs->tx_code,
530                                                             kInitialMetadata);
531   PerformStreamOp(gbs, &op);
532   grpc_core::ExecCtx::Get()->Flush();
533   recv_initial_metadata.notification.WaitForNotification();
534 
535   VerifyMetadataEqual(kInitialMetadata,
536                       recv_initial_metadata.grpc_initial_metadata);
537 }
538 
TEST_F(BinderTransportTest,PerformRecvInitialMetadataWithMethodRef)539 TEST_F(BinderTransportTest, PerformRecvInitialMetadataWithMethodRef) {
540   grpc_core::ExecCtx exec_ctx;
541   grpc_binder_stream* gbs = InitNewBinderStream();
542   grpc_transport_stream_op_batch op{};
543   grpc_transport_stream_op_batch_payload payload(nullptr);
544   op.payload = &payload;
545 
546   MakeRecvInitialMetadata recv_initial_metadata(&op);
547 
548   auto* gbt = reinterpret_cast<grpc_binder_transport*>(transport_);
549   const Metadata kInitialMetadataWithMethodRef =
550       AppendMethodRef(kDefaultMetadata, kDefaultMethodRef);
551   gbt->transport_stream_receiver->NotifyRecvInitialMetadata(
552       gbs->tx_code, kInitialMetadataWithMethodRef);
553   PerformStreamOp(gbs, &op);
554   grpc_core::ExecCtx::Get()->Flush();
555   recv_initial_metadata.notification.WaitForNotification();
556 
557   VerifyMetadataEqual(kInitialMetadataWithMethodRef,
558                       recv_initial_metadata.grpc_initial_metadata);
559 }
560 
TEST_F(BinderTransportTest,PerformRecvMessage)561 TEST_F(BinderTransportTest, PerformRecvMessage) {
562   grpc_core::ExecCtx exec_ctx;
563   grpc_binder_stream* gbs = InitNewBinderStream();
564   grpc_transport_stream_op_batch op{};
565   grpc_transport_stream_op_batch_payload payload(nullptr);
566   op.payload = &payload;
567 
568   MakeRecvMessage recv_message(&op);
569 
570   auto* gbt = reinterpret_cast<grpc_binder_transport*>(transport_);
571   const std::string kMessage = kDefaultMessage;
572   gbt->transport_stream_receiver->NotifyRecvMessage(gbs->tx_code, kMessage);
573 
574   PerformStreamOp(gbs, &op);
575   grpc_core::ExecCtx::Get()->Flush();
576   recv_message.notification.WaitForNotification();
577 
578   EXPECT_EQ(kMessage, recv_message.grpc_message->JoinIntoString());
579 }
580 
TEST_F(BinderTransportTest,PerformRecvTrailingMetadata)581 TEST_F(BinderTransportTest, PerformRecvTrailingMetadata) {
582   grpc_core::ExecCtx exec_ctx;
583   grpc_binder_stream* gbs = InitNewBinderStream();
584   grpc_transport_stream_op_batch op{};
585   grpc_transport_stream_op_batch_payload payload(nullptr);
586   op.payload = &payload;
587 
588   MakeRecvTrailingMetadata recv_trailing_metadata(&op);
589 
590   const Metadata kTrailingMetadata = kDefaultMetadata;
591   auto* gbt = reinterpret_cast<grpc_binder_transport*>(transport_);
592   constexpr int kStatus = kDefaultStatus;
593   gbt->transport_stream_receiver->NotifyRecvTrailingMetadata(
594       gbs->tx_code, kTrailingMetadata, kStatus);
595   PerformStreamOp(gbs, &op);
596   grpc_core::ExecCtx::Get()->Flush();
597   recv_trailing_metadata.notification.WaitForNotification();
598 
599   VerifyMetadataEqual(AppendStatus(kTrailingMetadata, kStatus),
600                       recv_trailing_metadata.grpc_trailing_metadata);
601 }
602 
TEST_F(BinderTransportTest,PerformRecvAll)603 TEST_F(BinderTransportTest, PerformRecvAll) {
604   grpc_core::ExecCtx exec_ctx;
605   grpc_binder_stream* gbs = InitNewBinderStream();
606   grpc_transport_stream_op_batch op{};
607   grpc_transport_stream_op_batch_payload payload(nullptr);
608   op.payload = &payload;
609 
610   MakeRecvInitialMetadata recv_initial_metadata(&op);
611   MakeRecvMessage recv_message(&op);
612   MakeRecvTrailingMetadata recv_trailing_metadata(&op);
613 
614   auto* gbt = reinterpret_cast<grpc_binder_transport*>(transport_);
615   const Metadata kInitialMetadataWithMethodRef =
616       AppendMethodRef(kDefaultMetadata, kDefaultMethodRef);
617   gbt->transport_stream_receiver->NotifyRecvInitialMetadata(
618       gbs->tx_code, kInitialMetadataWithMethodRef);
619 
620   const std::string kMessage = kDefaultMessage;
621   gbt->transport_stream_receiver->NotifyRecvMessage(gbs->tx_code, kMessage);
622 
623   Metadata trailing_metadata = kDefaultMetadata;
624   constexpr int kStatus = kDefaultStatus;
625   gbt->transport_stream_receiver->NotifyRecvTrailingMetadata(
626       gbs->tx_code, trailing_metadata, kStatus);
627   PerformStreamOp(gbs, &op);
628   grpc_core::ExecCtx::Get()->Flush();
629   recv_trailing_metadata.notification.WaitForNotification();
630 
631   VerifyMetadataEqual(kInitialMetadataWithMethodRef,
632                       recv_initial_metadata.grpc_initial_metadata);
633   trailing_metadata.emplace_back("grpc-status", std::to_string(kStatus));
634   VerifyMetadataEqual(trailing_metadata,
635                       recv_trailing_metadata.grpc_trailing_metadata);
636   EXPECT_EQ(kMessage, recv_message.grpc_message->JoinIntoString());
637 }
638 
TEST_F(BinderTransportTest,PerformAllOps)639 TEST_F(BinderTransportTest, PerformAllOps) {
640   grpc_core::ExecCtx exec_ctx;
641   grpc_binder_stream* gbs = InitNewBinderStream();
642   grpc_transport_stream_op_batch op{};
643   grpc_transport_stream_op_batch_payload payload(nullptr);
644   op.payload = &payload;
645 
646   const Metadata kSendInitialMetadata = kDefaultMetadata;
647   const std::string kMethodRef = kDefaultMethodRef;
648   MakeSendInitialMetadata send_initial_metadata(kSendInitialMetadata,
649                                                 kMethodRef, &op);
650 
651   const std::string kSendMessage = kDefaultMessage;
652   MakeSendMessage send_message(kSendMessage, &op);
653 
654   // The wireformat guarantees that suffix metadata will always be empty.
655   // TODO(waynetu): Check whether gRPC can internally add extra trailing
656   // metadata.
657   const Metadata kSendTrailingMetadata = {};
658   MakeSendTrailingMetadata send_trailing_metadata(kSendTrailingMetadata, &op);
659 
660   MockGrpcClosure mock_on_complete;
661   op.on_complete = mock_on_complete.GetGrpcClosure();
662 
663   // TODO(waynetu): Currently, we simply drop the prefix '/' from the :path
664   // argument to obtain the method name. Update the test if this turns out to be
665   // incorrect.
666   EXPECT_CALL(GetWireWriter(),
667               RpcCall(TransactionMatches(
668                   kFlagPrefix | kFlagMessageData | kFlagSuffix,
669                   kMethodRef.substr(1), kSendInitialMetadata, kSendMessage)));
670   Expectation on_complete = EXPECT_CALL(mock_on_complete, Callback);
671 
672   // Recv callbacks can happen after the on_complete callback.
673   MakeRecvInitialMetadata recv_initial_metadata(
674       &op, /* call_before = */ &on_complete);
675   MakeRecvMessage recv_message(&op, /* call_before = */ &on_complete);
676   MakeRecvTrailingMetadata recv_trailing_metadata(
677       &op, /* call_before = */ &on_complete);
678 
679   PerformStreamOp(gbs, &op);
680 
681   // Flush the execution context to force on_complete to run before recv
682   // callbacks get scheduled.
683   grpc_core::ExecCtx::Get()->Flush();
684 
685   auto* gbt = reinterpret_cast<grpc_binder_transport*>(transport_);
686   const Metadata kRecvInitialMetadata =
687       AppendMethodRef(kDefaultMetadata, kDefaultMethodRef);
688   gbt->transport_stream_receiver->NotifyRecvInitialMetadata(
689       gbs->tx_code, kRecvInitialMetadata);
690   const std::string kRecvMessage = kDefaultMessage;
691   gbt->transport_stream_receiver->NotifyRecvMessage(gbs->tx_code, kRecvMessage);
692   const Metadata kRecvTrailingMetadata = kDefaultMetadata;
693   constexpr int kStatus = 0x1234;
694   gbt->transport_stream_receiver->NotifyRecvTrailingMetadata(
695       gbs->tx_code, kRecvTrailingMetadata, kStatus);
696 
697   grpc_core::ExecCtx::Get()->Flush();
698   recv_initial_metadata.notification.WaitForNotification();
699   recv_message.notification.WaitForNotification();
700   recv_trailing_metadata.notification.WaitForNotification();
701 
702   VerifyMetadataEqual(kRecvInitialMetadata,
703                       recv_initial_metadata.grpc_initial_metadata);
704   VerifyMetadataEqual(AppendStatus(kRecvTrailingMetadata, kStatus),
705                       recv_trailing_metadata.grpc_trailing_metadata);
706 
707   EXPECT_EQ(kRecvMessage, recv_message.grpc_message->JoinIntoString());
708 }
709 
TEST_F(BinderTransportTest,WireWriterRpcCallErrorPropagates)710 TEST_F(BinderTransportTest, WireWriterRpcCallErrorPropagates) {
711   grpc_core::ExecCtx exec_ctx;
712   grpc_binder_stream* gbs = InitNewBinderStream();
713 
714   MockGrpcClosure mock_on_complete1;
715   MockGrpcClosure mock_on_complete2;
716 
717   EXPECT_CALL(GetWireWriter(), RpcCall)
718       .WillOnce(Return(absl::OkStatus()))
719       .WillOnce(Return(absl::InternalError("WireWriter::RpcCall failed")));
720   EXPECT_CALL(mock_on_complete1, Callback(absl::OkStatus()));
721   EXPECT_CALL(mock_on_complete2,
722               Callback(GrpcErrorMessageContains("WireWriter::RpcCall failed")));
723 
724   const Metadata kInitialMetadata = {};
725   grpc_transport_stream_op_batch op1{};
726   grpc_transport_stream_op_batch_payload payload1(nullptr);
727   op1.payload = &payload1;
728   MakeSendInitialMetadata send_initial_metadata1(kInitialMetadata, "", &op1);
729   op1.on_complete = mock_on_complete1.GetGrpcClosure();
730 
731   grpc_transport_stream_op_batch op2{};
732   grpc_transport_stream_op_batch_payload payload2(nullptr);
733   op2.payload = &payload2;
734   MakeSendInitialMetadata send_initial_metadata2(kInitialMetadata, "", &op2);
735   op2.on_complete = mock_on_complete2.GetGrpcClosure();
736 
737   PerformStreamOp(gbs, &op1);
738   PerformStreamOp(gbs, &op2);
739   grpc_core::ExecCtx::Get()->Flush();
740 }
741 
742 }  // namespace grpc_binder
743 
main(int argc,char ** argv)744 int main(int argc, char** argv) {
745   ::testing::InitGoogleTest(&argc, argv);
746   grpc::testing::TestEnvironment env(&argc, argv);
747   return RUN_ALL_TESTS();
748 }
749