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 #include "test/core/transport/binder/end2end/fake_binder.h"
16 
17 #include <algorithm>
18 #include <random>
19 #include <string>
20 #include <utility>
21 
22 #include <gmock/gmock.h>
23 #include <gtest/gtest.h>
24 
25 #include "absl/strings/str_format.h"
26 #include "absl/time/time.h"
27 
28 #include "test/core/util/test_config.h"
29 
30 namespace grpc_binder {
31 namespace end2end_testing {
32 namespace {
33 
34 class FakeBinderTest : public ::testing::TestWithParam<absl::Duration> {
35  public:
FakeBinderTest()36   FakeBinderTest() {
37     g_transaction_processor = new TransactionProcessor(GetParam());
38   }
~FakeBinderTest()39   ~FakeBinderTest() override { delete g_transaction_processor; }
40 };
41 
42 }  // namespace
43 
TEST_P(FakeBinderTest,SendInt32)44 TEST_P(FakeBinderTest, SendInt32) {
45   constexpr int kValue = 0x1234;
46   constexpr int kTxCode = 0x4321;
47   int called = 0;
48   std::unique_ptr<Binder> sender;
49   std::unique_ptr<TransactionReceiver> tx_receiver;
50   std::tie(sender, tx_receiver) = NewBinderPair(
51       [&](transaction_code_t tx_code, ReadableParcel* parcel, int /*uid*/) {
52         EXPECT_EQ(tx_code, kTxCode);
53         int value = 0;
54         EXPECT_TRUE(parcel->ReadInt32(&value).ok());
55         EXPECT_EQ(value, kValue);
56         called++;
57         return absl::OkStatus();
58       });
59 
60   EXPECT_TRUE(sender->PrepareTransaction().ok());
61   WritableParcel* parcel = sender->GetWritableParcel();
62   EXPECT_TRUE(parcel->WriteInt32(kValue).ok());
63   EXPECT_TRUE(sender->Transact(BinderTransportTxCode(kTxCode)).ok());
64 
65   g_transaction_processor->Terminate();
66   EXPECT_EQ(called, 1);
67 }
68 
TEST_P(FakeBinderTest,SendString)69 TEST_P(FakeBinderTest, SendString) {
70   constexpr char kValue[] = "example-string";
71   constexpr int kTxCode = 0x4321;
72   int called = 0;
73   std::unique_ptr<Binder> sender;
74   std::unique_ptr<TransactionReceiver> tx_receiver;
75   std::tie(sender, tx_receiver) = NewBinderPair(
76       [&](transaction_code_t tx_code, ReadableParcel* parcel, int /*uid*/) {
77         EXPECT_EQ(tx_code, kTxCode);
78         std::string value;
79         EXPECT_TRUE(parcel->ReadString(&value).ok());
80         EXPECT_STREQ(value.c_str(), kValue);
81         called++;
82         return absl::OkStatus();
83       });
84 
85   EXPECT_TRUE(sender->PrepareTransaction().ok());
86   WritableParcel* parcel = sender->GetWritableParcel();
87   EXPECT_TRUE(parcel->WriteString(kValue).ok());
88   EXPECT_TRUE(sender->Transact(BinderTransportTxCode(kTxCode)).ok());
89 
90   g_transaction_processor->Terminate();
91   EXPECT_EQ(called, 1);
92 }
93 
TEST_P(FakeBinderTest,SendByteArray)94 TEST_P(FakeBinderTest, SendByteArray) {
95   constexpr char kValue[] = "example-byte-array";
96   constexpr int kTxCode = 0x4321;
97   int called = 0;
98   std::unique_ptr<Binder> sender;
99   std::unique_ptr<TransactionReceiver> tx_receiver;
100   std::tie(sender, tx_receiver) = NewBinderPair(
101       [&](transaction_code_t tx_code, ReadableParcel* parcel, int /*uid*/) {
102         EXPECT_EQ(tx_code, kTxCode);
103         std::string value;
104         EXPECT_TRUE(parcel->ReadByteArray(&value).ok());
105         EXPECT_EQ(value, kValue);
106         called++;
107         return absl::OkStatus();
108       });
109 
110   EXPECT_TRUE(sender->PrepareTransaction().ok());
111   WritableParcel* parcel = sender->GetWritableParcel();
112   EXPECT_TRUE(parcel
113                   ->WriteByteArray(reinterpret_cast<const int8_t*>(kValue),
114                                    strlen(kValue))
115                   .ok());
116   EXPECT_TRUE(sender->Transact(BinderTransportTxCode(kTxCode)).ok());
117 
118   g_transaction_processor->Terminate();
119   EXPECT_EQ(called, 1);
120 }
121 
TEST_P(FakeBinderTest,SendMultipleItems)122 TEST_P(FakeBinderTest, SendMultipleItems) {
123   constexpr char kByteArray[] = "example-byte-array";
124   constexpr char kString[] = "example-string";
125   constexpr int kValue = 0x1234;
126   constexpr int kTxCode = 0x4321;
127   int called = 0;
128   std::unique_ptr<Binder> sender;
129   std::unique_ptr<TransactionReceiver> tx_receiver;
130   std::tie(sender, tx_receiver) = NewBinderPair(
131       [&](transaction_code_t tx_code, ReadableParcel* parcel, int /*uid*/) {
132         int value_result;
133         EXPECT_EQ(tx_code, kTxCode);
134         EXPECT_TRUE(parcel->ReadInt32(&value_result).ok());
135         EXPECT_EQ(value_result, kValue);
136         std::string byte_array_result;
137         EXPECT_TRUE(parcel->ReadByteArray(&byte_array_result).ok());
138         EXPECT_EQ(byte_array_result, kByteArray);
139         std::string string_result;
140         EXPECT_TRUE(parcel->ReadString(&string_result).ok());
141         EXPECT_STREQ(string_result.c_str(), kString);
142         called++;
143         return absl::OkStatus();
144       });
145 
146   EXPECT_TRUE(sender->PrepareTransaction().ok());
147   WritableParcel* parcel = sender->GetWritableParcel();
148   EXPECT_TRUE(parcel->WriteInt32(kValue).ok());
149   EXPECT_TRUE(parcel
150                   ->WriteByteArray(reinterpret_cast<const int8_t*>(kByteArray),
151                                    strlen(kByteArray))
152                   .ok());
153   EXPECT_TRUE(parcel->WriteString(kString).ok());
154   EXPECT_TRUE(sender->Transact(BinderTransportTxCode(kTxCode)).ok());
155 
156   g_transaction_processor->Terminate();
157   EXPECT_EQ(called, 1);
158 }
159 
TEST_P(FakeBinderTest,SendBinder)160 TEST_P(FakeBinderTest, SendBinder) {
161   constexpr int kValue = 0x1234;
162   constexpr int kTxCode = 0x4321;
163   int called = 0;
164   std::unique_ptr<Binder> sender;
165   std::unique_ptr<TransactionReceiver> tx_receiver;
166   std::tie(sender, tx_receiver) = NewBinderPair(
167       [&](transaction_code_t tx_code, ReadableParcel* parcel, int /*uid*/) {
168         EXPECT_EQ(tx_code, kTxCode);
169         std::unique_ptr<Binder> binder;
170         EXPECT_TRUE(parcel->ReadBinder(&binder).ok());
171         EXPECT_TRUE(binder->PrepareTransaction().ok());
172         WritableParcel* writable_parcel = binder->GetWritableParcel();
173         EXPECT_TRUE(writable_parcel->WriteInt32(kValue).ok());
174         EXPECT_TRUE(binder->Transact(BinderTransportTxCode(kTxCode + 1)).ok());
175         called++;
176         return absl::OkStatus();
177       });
178 
179   int called2 = 0;
180   std::unique_ptr<TransactionReceiver> tx_receiver2 =
181       absl::make_unique<FakeTransactionReceiver>(
182           nullptr,
183           [&](transaction_code_t tx_code, ReadableParcel* parcel, int /*uid*/) {
184             int value;
185             EXPECT_TRUE(parcel->ReadInt32(&value).ok());
186             EXPECT_EQ(value, kValue);
187             EXPECT_EQ(tx_code, kTxCode + 1);
188             called2++;
189             return absl::OkStatus();
190           });
191   EXPECT_TRUE(sender->PrepareTransaction().ok());
192   WritableParcel* parcel = sender->GetWritableParcel();
193   EXPECT_TRUE(parcel->WriteBinder(tx_receiver2.get()).ok());
194   EXPECT_TRUE(sender->Transact(BinderTransportTxCode(kTxCode)).ok());
195 
196   g_transaction_processor->Terminate();
197   EXPECT_EQ(called, 1);
198   EXPECT_EQ(called2, 1);
199 }
200 
TEST_P(FakeBinderTest,SendTransactionAfterDestruction)201 TEST_P(FakeBinderTest, SendTransactionAfterDestruction) {
202   constexpr int kValue = 0x1234;
203   constexpr int kTxCode = 0x4321;
204   std::unique_ptr<Binder> sender;
205   int called = 0;
206   {
207     std::unique_ptr<TransactionReceiver> tx_receiver;
208     std::tie(sender, tx_receiver) = NewBinderPair(
209         [&](transaction_code_t tx_code, ReadableParcel* parcel, int /*uid*/) {
210           EXPECT_EQ(tx_code, kTxCode);
211           int value;
212           EXPECT_TRUE(parcel->ReadInt32(&value).ok());
213           EXPECT_EQ(value, kValue + called);
214           called++;
215           return absl::OkStatus();
216         });
217     EXPECT_TRUE(sender->PrepareTransaction().ok());
218     WritableParcel* parcel = sender->GetWritableParcel();
219     EXPECT_TRUE(parcel->WriteInt32(kValue).ok());
220     EXPECT_TRUE(sender->Transact(BinderTransportTxCode(kTxCode)).ok());
221   }
222   // tx_receiver gets destructed here. This additional transaction should
223   // *still* be received.
224   EXPECT_TRUE(sender->PrepareTransaction().ok());
225   WritableParcel* parcel = sender->GetWritableParcel();
226   EXPECT_TRUE(parcel->WriteInt32(kValue + 1).ok());
227   EXPECT_TRUE(sender->Transact(BinderTransportTxCode(kTxCode)).ok());
228 
229   g_transaction_processor->Terminate();
230   EXPECT_EQ(called, 2);
231 }
232 
233 namespace {
234 
235 struct ThreadArgument {
236   int tid;
237   std::vector<std::vector<std::pair<std::unique_ptr<Binder>,
238                                     std::unique_ptr<TransactionReceiver>>>>*
239       global_binder_pairs;
240   std::vector<std::vector<int>>* global_cnts;
241   int tx_code;
242   int num_pairs_per_thread;
243   int num_transactions_per_pair;
244   grpc_core::Mutex* mu;
245 };
246 
247 }  // namespace
248 
249 // Verify that this system works correctly in a concurrent environment.
250 //
251 // In end-to-end tests, there will be at least two threads, one from client to
252 // server and vice versa. Thus, it's important for us to make sure that the
253 // simulation is correct in such setup.
TEST_P(FakeBinderTest,StressTest)254 TEST_P(FakeBinderTest, StressTest) {
255   constexpr int kTxCode = 0x4321;
256   constexpr int kNumThreads = 16;
257   constexpr int kNumPairsPerThread = 128;
258   constexpr int kNumTransactionsPerPair = 128;
259   std::vector<ThreadArgument> args(kNumThreads);
260 
261   grpc_core::Mutex mu;
262   std::vector<std::vector<
263       std::pair<std::unique_ptr<Binder>, std::unique_ptr<TransactionReceiver>>>>
264       global_binder_pairs(kNumThreads);
265   std::vector<std::vector<int>> global_cnts(
266       kNumThreads, std::vector<int>(kNumPairsPerThread, 0));
267 
268   auto th_function = [](void* arg) {
269     ThreadArgument* th_arg = static_cast<ThreadArgument*>(arg);
270     int tid = th_arg->tid;
271     std::vector<std::pair<std::unique_ptr<Binder>,
272                           std::unique_ptr<TransactionReceiver>>>
273         binder_pairs;
274     for (int p = 0; p < th_arg->num_pairs_per_thread; ++p) {
275       std::unique_ptr<Binder> binder;
276       std::unique_ptr<TransactionReceiver> tx_receiver;
277       int expected_tx_code = th_arg->tx_code;
278       std::vector<std::vector<int>>* cnt = th_arg->global_cnts;
279       std::tie(binder, tx_receiver) =
280           NewBinderPair([tid, p, cnt, expected_tx_code](
281                             transaction_code_t tx_code, ReadableParcel* parcel,
282                             int /*uid*/) mutable {
283             EXPECT_EQ(tx_code, expected_tx_code);
284             int value;
285             EXPECT_TRUE(parcel->ReadInt32(&value).ok());
286             EXPECT_EQ(tid, value);
287             EXPECT_TRUE(parcel->ReadInt32(&value).ok());
288             EXPECT_EQ(p, value);
289             EXPECT_TRUE(parcel->ReadInt32(&value).ok());
290             EXPECT_EQ((*cnt)[tid][p], value);
291             (*cnt)[tid][p]++;
292             return absl::OkStatus();
293           });
294       binder_pairs.emplace_back(std::move(binder), std::move(tx_receiver));
295     }
296     std::vector<int> order;
297     for (int i = 0; i < th_arg->num_pairs_per_thread; ++i) {
298       for (int j = 0; j < th_arg->num_transactions_per_pair; ++j) {
299         order.emplace_back(i);
300       }
301     }
302     std::mt19937 rng(tid);
303     std::shuffle(order.begin(), order.end(), rng);
304     std::vector<int> tx_cnt(th_arg->num_pairs_per_thread);
305     for (int p : order) {
306       EXPECT_TRUE(binder_pairs[p].first->PrepareTransaction().ok());
307       WritableParcel* parcel = binder_pairs[p].first->GetWritableParcel();
308       EXPECT_TRUE(parcel->WriteInt32(th_arg->tid).ok());
309       EXPECT_TRUE(parcel->WriteInt32(p).ok());
310       EXPECT_TRUE(parcel->WriteInt32(tx_cnt[p]++).ok());
311       EXPECT_TRUE(binder_pairs[p]
312                       .first->Transact(BinderTransportTxCode(th_arg->tx_code))
313                       .ok());
314     }
315     th_arg->mu->Lock();
316     (*th_arg->global_binder_pairs)[tid] = std::move(binder_pairs);
317     th_arg->mu->Unlock();
318   };
319 
320   std::vector<grpc_core::Thread> thrs(kNumThreads);
321   std::vector<std::string> thr_names(kNumThreads);
322   for (int i = 0; i < kNumThreads; ++i) {
323     args[i].tid = i;
324     args[i].global_binder_pairs = &global_binder_pairs;
325     args[i].global_cnts = &global_cnts;
326     args[i].tx_code = kTxCode;
327     args[i].num_pairs_per_thread = kNumPairsPerThread;
328     args[i].num_transactions_per_pair = kNumTransactionsPerPair;
329     args[i].mu = &mu;
330     thr_names[i] = absl::StrFormat("thread-%d", i);
331     thrs[i] = grpc_core::Thread(thr_names[i].c_str(), th_function, &args[i]);
332   }
333   for (auto& th : thrs) th.Start();
334   for (auto& th : thrs) th.Join();
335   g_transaction_processor->Terminate();
336 }
337 
338 INSTANTIATE_TEST_SUITE_P(FakeBinderTestWithDifferentDelayTimes, FakeBinderTest,
339                          testing::Values(absl::ZeroDuration(),
340                                          absl::Nanoseconds(10),
341                                          absl::Microseconds(10)));
342 
343 }  // namespace end2end_testing
344 }  // namespace grpc_binder
345 
main(int argc,char ** argv)346 int main(int argc, char** argv) {
347   ::testing::InitGoogleTest(&argc, argv);
348   grpc::testing::TestEnvironment env(argc, argv);
349   return RUN_ALL_TESTS();
350 }
351