fake_binder_test.cc
Go to the documentation of this file.
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 
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 
29 
30 namespace grpc_binder {
31 namespace end2end_testing {
32 namespace {
33 
34 class FakeBinderTest : public ::testing::TestWithParam<absl::Duration> {
35  public:
36  FakeBinderTest() {
37  g_transaction_processor = new TransactionProcessor(GetParam());
38  }
39  ~FakeBinderTest() override { delete g_transaction_processor; }
40 };
41 
42 } // namespace
43 
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 
66  EXPECT_EQ(called, 1);
67 }
68 
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);
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 
91  EXPECT_EQ(called, 1);
92 }
93 
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);
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 
119  EXPECT_EQ(called, 1);
120 }
121 
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 
157  EXPECT_EQ(called, 1);
158 }
159 
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 
197  EXPECT_EQ(called, 1);
198  EXPECT_EQ(called2, 1);
199 }
200 
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 
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>>>>*
240  std::vector<std::vector<int>>* global_cnts;
241  int tx_code;
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.
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 
262  std::vector<std::vector<
263  std::pair<std::unique_ptr<Binder>, std::unique_ptr<TransactionReceiver>>>>
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](
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();
336 }
337 
338 INSTANTIATE_TEST_SUITE_P(FakeBinderTestWithDifferentDelayTimes, FakeBinderTest,
340  absl::Nanoseconds(10),
341  absl::Microseconds(10)));
342 
343 } // namespace end2end_testing
344 } // namespace grpc_binder
345 
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 }
global_cnts
std::vector< std::vector< int > > * global_cnts
Definition: fake_binder_test.cc:240
mu
grpc_core::Mutex * mu
Definition: fake_binder_test.cc:244
generate.env
env
Definition: generate.py:37
absl::ZeroDuration
constexpr Duration ZeroDuration()
Definition: third_party/abseil-cpp/absl/time/time.h:308
absl::StrFormat
ABSL_MUST_USE_RESULT std::string StrFormat(const FormatSpec< Args... > &format, const Args &... args)
Definition: abseil-cpp/absl/strings/str_format.h:338
main
int main(int argc, char **argv)
Definition: fake_binder_test.cc:346
absl::Nanoseconds
constexpr Duration Nanoseconds(T n)
Definition: third_party/abseil-cpp/absl/time/time.h:407
grpc_binder
Definition: connection_id_generator.cc:45
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
transaction_code_t
uint32_t transaction_code_t
Definition: binder_constants.h:24
absl::OkStatus
Status OkStatus()
Definition: third_party/abseil-cpp/absl/status/status.h:882
grpc_binder::WritableParcel::WriteString
virtual absl::Status WriteString(absl::string_view s)=0
tx_code
int tx_code
Definition: fake_binder_test.cc:241
testing::TestWithParam
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1883
EXPECT_EQ
#define EXPECT_EQ(a, b)
Definition: iomgr/time_averaged_stats_test.cc:27
tid
int tid
Definition: fake_binder_test.cc:236
grpc_binder::BinderTransportTxCode
BinderTransportTxCode
Definition: binder_constants.h:31
absl::Microseconds
constexpr Duration Microseconds(T n)
Definition: third_party/abseil-cpp/absl/time/time.h:411
asyncio_get_stats.args
args
Definition: asyncio_get_stats.py:40
absl::move
constexpr absl::remove_reference_t< T > && move(T &&t) noexcept
Definition: abseil-cpp/absl/utility/utility.h:221
gen_stats_data.c_str
def c_str(s, encoding='ascii')
Definition: gen_stats_data.py:38
num_transactions_per_pair
int num_transactions_per_pair
Definition: fake_binder_test.cc:243
grpc_binder::end2end_testing::INSTANTIATE_TEST_SUITE_P
INSTANTIATE_TEST_SUITE_P(FakeBinderTestWithDifferentDelayTimes, FakeBinderTest, testing::Values(absl::ZeroDuration(), absl::Nanoseconds(10), absl::Microseconds(10)))
grpc_binder::ReadableParcel::ReadBinder
virtual absl::Status ReadBinder(std::unique_ptr< Binder > *data)=0
RUN_ALL_TESTS
int RUN_ALL_TESTS() GTEST_MUST_USE_RESULT_
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2471
grpc_binder::WritableParcel
Definition: binder.h:44
grpc_binder::ReadableParcel::ReadByteArray
virtual absl::Status ReadByteArray(std::string *data)=0
grpc_binder::end2end_testing::TEST_P
TEST_P(FakeBinderTest, SendInt32)
Definition: fake_binder_test.cc:44
grpc_binder::end2end_testing::NewBinderPair
std::pair< std::unique_ptr< Binder >, std::unique_ptr< TransactionReceiver > > NewBinderPair(TransactionReceiver::OnTransactCb transact_cb)
Definition: fake_binder.cc:267
test_config.h
value
const char * value
Definition: hpack_parser_table.cc:165
EXPECT_STREQ
#define EXPECT_STREQ(s1, s2)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2095
grpc_core::Mutex
Definition: src/core/lib/gprpp/sync.h:61
testing::InitGoogleTest
GTEST_API_ void InitGoogleTest(int *argc, char **argv)
Definition: bloaty/third_party/googletest/googletest/src/gtest.cc:6106
grpc_binder::end2end_testing::TransactionProcessor::Terminate
void Terminate()
Definition: fake_binder.cc:172
testing::Values
internal::ValueArray< T... > Values(T... v)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest-param-test.h:335
grpc_binder::WritableParcel::WriteInt32
virtual absl::Status WriteInt32(int32_t data)=0
kNumThreads
const int kNumThreads
Definition: thread_stress_test.cc:46
first
StrT first
Definition: cxa_demangle.cpp:4884
grpc_binder::WritableParcel::WriteBinder
virtual absl::Status WriteBinder(HasRawBinder *binder)=0
grpc::testing::TestEnvironment
Definition: test/core/util/test_config.h:54
ok
bool ok
Definition: async_end2end_test.cc:197
arg
struct arg arg
grpc_binder::ReadableParcel::ReadString
virtual absl::Status ReadString(std::string *str)=0
absl::Status::ok
ABSL_MUST_USE_RESULT bool ok() const
Definition: third_party/abseil-cpp/absl/status/status.h:802
grpc_core::Thread
Definition: thd.h:43
grpc_binder::ReadableParcel::ReadInt32
virtual absl::Status ReadInt32(int32_t *data)=0
EXPECT_TRUE
#define EXPECT_TRUE(condition)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1967
global_binder_pairs
std::vector< std::vector< std::pair< std::unique_ptr< Binder >, std::unique_ptr< TransactionReceiver > > > > * global_binder_pairs
Definition: fake_binder_test.cc:239
num_pairs_per_thread
int num_pairs_per_thread
Definition: fake_binder_test.cc:242
int8_t
signed char int8_t
Definition: stdint-msvc2008.h:75
fake_binder.h
grpc_binder::ReadableParcel
Definition: binder.h:66
grpc_binder::end2end_testing::g_transaction_processor
TransactionProcessor * g_transaction_processor
Definition: fake_binder.cc:25
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230


grpc
Author(s):
autogenerated on Fri May 16 2025 02:58:22