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 = μ
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