1 #include <pdx/client.h>
2
3 #include <gmock/gmock.h>
4 #include <sys/eventfd.h>
5
6 #include <pdx/mock_client_channel.h>
7 #include <pdx/mock_client_channel_factory.h>
8 #include <pdx/rpc/remote_method.h>
9
10 using android::pdx::BorrowedChannelHandle;
11 using android::pdx::BorrowedHandle;
12 using android::pdx::ClientBase;
13 using android::pdx::ClientChannel;
14 using android::pdx::ClientChannelFactory;
15 using android::pdx::ErrorStatus;
16 using android::pdx::LocalChannelHandle;
17 using android::pdx::LocalHandle;
18 using android::pdx::MockClientChannel;
19 using android::pdx::MockClientChannelFactory;
20 using android::pdx::RemoteChannelHandle;
21 using android::pdx::RemoteHandle;
22 using android::pdx::Status;
23 using android::pdx::Transaction;
24 using android::pdx::rpc::Void;
25
26 using testing::A;
27 using testing::AnyNumber;
28 using testing::ByMove;
29 using testing::Invoke;
30 using testing::Ne;
31 using testing::Return;
32 using testing::_;
33
34 namespace {
35
IntToPtr(intptr_t addr)36 inline void* IntToPtr(intptr_t addr) { return reinterpret_cast<void*>(addr); }
IntToConstPtr(intptr_t addr)37 inline const void* IntToConstPtr(intptr_t addr) {
38 return reinterpret_cast<const void*>(addr);
39 }
40
41 struct TestInterface final {
42 // Op codes.
43 enum {
44 kOpAdd = 0,
45 kOpSendFile,
46 kOpGetFile,
47 kOpPushChannel,
48 };
49
50 // Methods.
51 PDX_REMOTE_METHOD(Add, kOpAdd, int(int, int));
52 PDX_REMOTE_METHOD(SendFile, kOpSendFile, void(const LocalHandle& fd));
53 PDX_REMOTE_METHOD(GetFile, kOpGetFile, LocalHandle(const std::string&, int));
54 PDX_REMOTE_METHOD(PushChannel, kOpPushChannel, LocalChannelHandle(Void));
55
56 PDX_REMOTE_API(API, Add, SendFile, GetFile, PushChannel);
57 };
58
59 class SimpleClient : public ClientBase<SimpleClient> {
60 public:
SimpleClient(std::unique_ptr<ClientChannel> channel)61 explicit SimpleClient(std::unique_ptr<ClientChannel> channel)
62 : BASE{std::move(channel)} {}
SimpleClient(std::unique_ptr<ClientChannelFactory> channel_factory,int64_t timeout_ms)63 SimpleClient(std::unique_ptr<ClientChannelFactory> channel_factory,
64 int64_t timeout_ms)
65 : BASE{std::move(channel_factory), timeout_ms} {
66 EnableAutoReconnect(timeout_ms);
67 }
68
69 using BASE::SendImpulse;
70 using BASE::InvokeRemoteMethod;
71 using BASE::InvokeRemoteMethodInPlace;
72 using BASE::Close;
73 using BASE::IsConnected;
74 using BASE::EnableAutoReconnect;
75 using BASE::DisableAutoReconnect;
76 using BASE::event_fd;
77 using BASE::GetChannel;
78
79 MOCK_METHOD0(OnConnect, void());
80 };
81
82 class FailingClient : public ClientBase<FailingClient> {
83 public:
FailingClient(std::unique_ptr<ClientChannel> channel,int error_code)84 explicit FailingClient(std::unique_ptr<ClientChannel> channel, int error_code)
85 : BASE{std::move(channel)} {
86 Close(error_code);
87 }
88 };
89
90 class ClientChannelTest : public testing::Test {
91 public:
ClientChannelTest()92 ClientChannelTest()
93 : client_{SimpleClient::Create(
94 std::make_unique<testing::StrictMock<MockClientChannel>>())} {}
95
mock_channel()96 MockClientChannel* mock_channel() {
97 return static_cast<MockClientChannel*>(client_->GetChannel());
98 }
99
100 std::unique_ptr<SimpleClient> client_;
101 };
102
103 class ClientChannelFactoryTest : public testing::Test {
104 public:
ClientChannelFactoryTest()105 ClientChannelFactoryTest() {
106 auto factory =
107 std::make_unique<testing::NiceMock<MockClientChannelFactory>>();
108 ON_CALL(*factory, Connect(kTimeout))
109 .WillByDefault(Invoke(this, &ClientChannelFactoryTest::OnConnect));
110 client_ = SimpleClient::Create(std::move(factory), kTimeout);
111 }
112
mock_channel()113 MockClientChannel* mock_channel() {
114 return static_cast<MockClientChannel*>(client_->GetChannel());
115 }
116
OnConnect(int64_t)117 Status<std::unique_ptr<ClientChannel>> OnConnect(int64_t /*timeout_ms*/) {
118 if (on_connect_error_)
119 return ErrorStatus(on_connect_error_);
120 std::unique_ptr<MockClientChannel> channel =
121 std::make_unique<testing::StrictMock<MockClientChannel>>();
122 if (on_connect_callback_)
123 on_connect_callback_(channel.get());
124 return Status<std::unique_ptr<ClientChannel>>{std::move(channel)};
125 }
126
OnConnectCallback(std::function<void (MockClientChannel *)> callback)127 void OnConnectCallback(std::function<void(MockClientChannel*)> callback) {
128 on_connect_callback_ = callback;
129 }
SetOnConnectError(int error)130 void SetOnConnectError(int error) { on_connect_error_ = error; }
ResetOnConnectError()131 void ResetOnConnectError() { on_connect_error_ = 0; }
132
133 constexpr static int64_t kTimeout = 123;
134 std::unique_ptr<SimpleClient> client_;
135 std::function<void(MockClientChannel*)> on_connect_callback_;
136 int on_connect_error_{0};
137 };
138
139 constexpr int64_t ClientChannelFactoryTest::kTimeout;
140
141 class ClientTransactionTest : public ClientChannelTest {
142 public:
ClientTransactionTest()143 ClientTransactionTest() : transaction_{*client_} {}
144
145 Transaction transaction_;
146 };
147
148 } // anonymous namespace
149
TEST_F(ClientChannelTest,IsInitialized)150 TEST_F(ClientChannelTest, IsInitialized) {
151 ASSERT_NE(client_.get(), nullptr);
152 EXPECT_TRUE(client_->IsInitialized());
153 EXPECT_TRUE(client_->IsConnected());
154 }
155
TEST_F(ClientChannelTest,CloseOnConstruction)156 TEST_F(ClientChannelTest, CloseOnConstruction) {
157 FailingClient failed_client1{std::make_unique<MockClientChannel>(), EACCES};
158 ASSERT_FALSE(failed_client1.IsInitialized());
159 EXPECT_EQ(-EACCES, failed_client1.error());
160
161 FailingClient failed_client2{std::make_unique<MockClientChannel>(), -EACCES};
162 ASSERT_FALSE(failed_client2.IsInitialized());
163 EXPECT_EQ(-EACCES, failed_client2.error());
164
165 auto failed_client3 =
166 FailingClient::Create(std::make_unique<MockClientChannel>(), EIO);
167 ASSERT_EQ(failed_client3.get(), nullptr);
168 }
169
TEST_F(ClientChannelTest,IsConnected)170 TEST_F(ClientChannelTest, IsConnected) {
171 EXPECT_TRUE(client_->IsConnected());
172 EXPECT_EQ(0, client_->error());
173 client_->Close(-EINVAL);
174 EXPECT_FALSE(client_->IsConnected());
175 EXPECT_EQ(-EINVAL, client_->error());
176 }
177
TEST_F(ClientChannelTest,event_fd)178 TEST_F(ClientChannelTest, event_fd) {
179 EXPECT_CALL(*mock_channel(), event_fd()).WillOnce(Return(12));
180 EXPECT_EQ(12, client_->event_fd());
181 }
182
TEST_F(ClientChannelTest,SendImpulse)183 TEST_F(ClientChannelTest, SendImpulse) {
184 EXPECT_CALL(*mock_channel(), SendImpulse(123, nullptr, 0))
185 .WillOnce(Return(Status<void>{}));
186 EXPECT_TRUE(client_->SendImpulse(123));
187
188 EXPECT_CALL(*mock_channel(), SendImpulse(17, nullptr, 0))
189 .WillOnce(Return(ErrorStatus{EIO}));
190 auto status = client_->SendImpulse(17);
191 ASSERT_FALSE(status);
192 EXPECT_EQ(EIO, status.error());
193
194 const void* const kTestPtr = IntToConstPtr(1234);
195 EXPECT_CALL(*mock_channel(), SendImpulse(1, kTestPtr, 17))
196 .WillOnce(Return(Status<void>{}));
197 EXPECT_TRUE(client_->SendImpulse(1, kTestPtr, 17));
198 }
199
TEST_F(ClientChannelTest,InvokeRemoteMethodNullTransactionState)200 TEST_F(ClientChannelTest, InvokeRemoteMethodNullTransactionState) {
201 EXPECT_CALL(*mock_channel(), AllocateTransactionState())
202 .WillOnce(Return(nullptr));
203 EXPECT_CALL(*mock_channel(),
204 SendWithInt(nullptr, TestInterface::kOpAdd, _, _, nullptr, 0))
205 .WillOnce(Return(9));
206 EXPECT_CALL(*mock_channel(), FreeTransactionState(nullptr));
207 EXPECT_TRUE(client_->InvokeRemoteMethod<TestInterface::Add>(4, 5));
208 }
209
TEST_F(ClientChannelTest,InvokeRemoteMethodAddSuccess)210 TEST_F(ClientChannelTest, InvokeRemoteMethodAddSuccess) {
211 void* const kTransactionState = IntToPtr(123);
212 EXPECT_CALL(*mock_channel(), AllocateTransactionState())
213 .WillOnce(Return(kTransactionState));
214 EXPECT_CALL(
215 *mock_channel(),
216 SendWithInt(kTransactionState, TestInterface::kOpAdd, _, _, nullptr, 0))
217 .WillOnce(Return(3));
218 EXPECT_CALL(*mock_channel(), FreeTransactionState(kTransactionState));
219 Status<int> status = client_->InvokeRemoteMethod<TestInterface::Add>(1, 2);
220 ASSERT_TRUE(status);
221 EXPECT_EQ(3, status.get());
222 }
223
TEST_F(ClientChannelTest,InvokeRemoteMethodAddFailure)224 TEST_F(ClientChannelTest, InvokeRemoteMethodAddFailure) {
225 void* const kTransactionState = IntToPtr(123);
226 EXPECT_CALL(*mock_channel(), AllocateTransactionState())
227 .WillOnce(Return(kTransactionState));
228 EXPECT_CALL(
229 *mock_channel(),
230 SendWithInt(kTransactionState, TestInterface::kOpAdd, _, _, nullptr, 0))
231 .WillOnce(Return(ErrorStatus{EIO}));
232 EXPECT_CALL(*mock_channel(), FreeTransactionState(kTransactionState));
233 Status<int> status = client_->InvokeRemoteMethod<TestInterface::Add>(1, 2);
234 ASSERT_FALSE(status);
235 EXPECT_EQ(EIO, status.error());
236 }
237
TEST_F(ClientChannelTest,InvokeRemoteMethodGetFileSuccess)238 TEST_F(ClientChannelTest, InvokeRemoteMethodGetFileSuccess) {
239 void* const kTransactionState = IntToPtr(123);
240 int fd = eventfd(0, 0);
241 EXPECT_CALL(*mock_channel(), AllocateTransactionState())
242 .WillOnce(Return(kTransactionState));
243 EXPECT_CALL(*mock_channel(),
244 SendWithFileHandle(kTransactionState, TestInterface::kOpGetFile,
245 _, _, nullptr, 0))
246 .WillOnce(Return(ByMove(LocalHandle{fd})));
247 EXPECT_CALL(*mock_channel(), FreeTransactionState(kTransactionState));
248 Status<LocalHandle> status =
249 client_->InvokeRemoteMethod<TestInterface::GetFile>();
250 ASSERT_TRUE(status);
251 EXPECT_EQ(fd, status.get().Get());
252 }
253
TEST_F(ClientChannelTest,InvokeRemoteMethodGetFileFailure)254 TEST_F(ClientChannelTest, InvokeRemoteMethodGetFileFailure) {
255 void* const kTransactionState = IntToPtr(123);
256 EXPECT_CALL(*mock_channel(), AllocateTransactionState())
257 .WillOnce(Return(kTransactionState));
258 EXPECT_CALL(*mock_channel(),
259 SendWithFileHandle(kTransactionState, TestInterface::kOpGetFile,
260 _, _, nullptr, 0))
261 .WillOnce(Return(ByMove(ErrorStatus{EACCES})));
262 EXPECT_CALL(*mock_channel(), FreeTransactionState(kTransactionState));
263 Status<LocalHandle> status =
264 client_->InvokeRemoteMethod<TestInterface::GetFile>("file", 0);
265 ASSERT_FALSE(status);
266 EXPECT_EQ(EACCES, status.error());
267 }
268
TEST_F(ClientChannelTest,InvokeRemoteMethodPushChannelSuccess)269 TEST_F(ClientChannelTest, InvokeRemoteMethodPushChannelSuccess) {
270 void* const kTransactionState = IntToPtr(123);
271 const int32_t kHandleValue = 17;
272 EXPECT_CALL(*mock_channel(), AllocateTransactionState())
273 .WillOnce(Return(kTransactionState));
274 EXPECT_CALL(
275 *mock_channel(),
276 SendWithChannelHandle(kTransactionState, TestInterface::kOpPushChannel, _,
277 _, nullptr, 0))
278 .WillOnce(Return(ByMove(LocalChannelHandle{nullptr, kHandleValue})));
279 EXPECT_CALL(*mock_channel(), FreeTransactionState(kTransactionState));
280 Status<LocalChannelHandle> status =
281 client_->InvokeRemoteMethod<TestInterface::PushChannel>();
282 ASSERT_TRUE(status);
283 EXPECT_EQ(kHandleValue, status.get().value());
284 }
285
TEST_F(ClientChannelTest,InvokeRemoteMethodPushChannelFailure)286 TEST_F(ClientChannelTest, InvokeRemoteMethodPushChannelFailure) {
287 void* const kTransactionState = IntToPtr(123);
288 EXPECT_CALL(*mock_channel(), AllocateTransactionState())
289 .WillOnce(Return(kTransactionState));
290 EXPECT_CALL(
291 *mock_channel(),
292 SendWithChannelHandle(kTransactionState, TestInterface::kOpPushChannel, _,
293 _, nullptr, 0))
294 .WillOnce(Return(ByMove(ErrorStatus{EACCES})));
295 EXPECT_CALL(*mock_channel(), FreeTransactionState(kTransactionState));
296 Status<LocalChannelHandle> status =
297 client_->InvokeRemoteMethod<TestInterface::PushChannel>();
298 ASSERT_FALSE(status);
299 EXPECT_EQ(EACCES, status.error());
300 }
301
TEST_F(ClientChannelTest,InvokeRemoteMethodSendFileSuccess)302 TEST_F(ClientChannelTest, InvokeRemoteMethodSendFileSuccess) {
303 void* const kTransactionState = IntToPtr(123);
304 LocalHandle fd{eventfd(0, 0)};
305 EXPECT_CALL(*mock_channel(), AllocateTransactionState())
306 .WillOnce(Return(kTransactionState));
307 EXPECT_CALL(*mock_channel(),
308 PushFileHandle(kTransactionState, A<const LocalHandle&>()))
309 .WillOnce(Return(1));
310 EXPECT_CALL(*mock_channel(),
311 SendWithInt(kTransactionState, TestInterface::kOpSendFile, _, _,
312 nullptr, 0))
313 .WillOnce(Return(0));
314 EXPECT_CALL(*mock_channel(), FreeTransactionState(kTransactionState));
315 EXPECT_TRUE(client_->InvokeRemoteMethod<TestInterface::SendFile>(fd));
316 }
317
TEST_F(ClientChannelTest,InvokeRemoteMethodSendFileFailure)318 TEST_F(ClientChannelTest, InvokeRemoteMethodSendFileFailure) {
319 void* const kTransactionState = IntToPtr(123);
320 LocalHandle fd{eventfd(0, 0)};
321 EXPECT_CALL(*mock_channel(), AllocateTransactionState())
322 .WillOnce(Return(kTransactionState));
323 EXPECT_CALL(*mock_channel(),
324 PushFileHandle(kTransactionState, A<const LocalHandle&>()))
325 .WillOnce(Return(1));
326 EXPECT_CALL(*mock_channel(),
327 SendWithInt(kTransactionState, TestInterface::kOpSendFile, _, _,
328 nullptr, 0))
329 .WillOnce(Return(ErrorStatus{EACCES}));
330 EXPECT_CALL(*mock_channel(), FreeTransactionState(kTransactionState));
331 EXPECT_FALSE(client_->InvokeRemoteMethod<TestInterface::SendFile>(fd));
332 }
333
TEST_F(ClientChannelFactoryTest,IsInitialized)334 TEST_F(ClientChannelFactoryTest, IsInitialized) {
335 ASSERT_NE(client_.get(), nullptr);
336 EXPECT_TRUE(client_->IsInitialized());
337 EXPECT_TRUE(client_->IsConnected());
338 }
339
TEST_F(ClientChannelFactoryTest,NotConnectedButInitialized)340 TEST_F(ClientChannelFactoryTest, NotConnectedButInitialized) {
341 auto factory =
342 std::make_unique<testing::NiceMock<MockClientChannelFactory>>();
343 EXPECT_CALL(*factory, Connect(kTimeout))
344 .WillOnce(Return(ByMove(ErrorStatus(ESHUTDOWN))))
345 .WillOnce(Invoke(this, &ClientChannelFactoryTest::OnConnect));
346 client_ = SimpleClient::Create(std::move(factory), kTimeout);
347 ASSERT_NE(client_.get(), nullptr);
348 EXPECT_TRUE(client_->IsInitialized());
349 EXPECT_FALSE(client_->IsConnected());
350 client_->DisableAutoReconnect();
351 ASSERT_FALSE(client_->SendImpulse(17));
352 EXPECT_FALSE(client_->IsConnected());
353 client_->EnableAutoReconnect(kTimeout);
354 EXPECT_CALL(*client_, OnConnect());
355 OnConnectCallback([](auto* mock) {
356 EXPECT_CALL(*mock, SendImpulse(17, nullptr, 0))
357 .WillOnce(Return(Status<void>{}));
358 });
359 ASSERT_TRUE(client_->SendImpulse(17));
360 EXPECT_TRUE(client_->IsConnected());
361 }
362
TEST_F(ClientChannelFactoryTest,CheckDisconnect)363 TEST_F(ClientChannelFactoryTest, CheckDisconnect) {
364 EXPECT_CALL(*mock_channel(), SendImpulse(17, nullptr, 0))
365 .WillOnce(Return(ErrorStatus{ESHUTDOWN}));
366 ASSERT_FALSE(client_->SendImpulse(17));
367 EXPECT_FALSE(client_->IsConnected());
368 EXPECT_EQ(-ESHUTDOWN, client_->error());
369 }
370
TEST_F(ClientChannelFactoryTest,CheckReconnect)371 TEST_F(ClientChannelFactoryTest, CheckReconnect) {
372 client_->Close(ESHUTDOWN);
373 ASSERT_FALSE(client_->IsConnected());
374
375 EXPECT_CALL(*client_, OnConnect());
376 OnConnectCallback([](auto* mock) {
377 EXPECT_CALL(*mock, SendImpulse(17, nullptr, 0))
378 .WillOnce(Return(Status<void>{}));
379 });
380 ASSERT_TRUE(client_->SendImpulse(17));
381 EXPECT_TRUE(client_->IsConnected());
382 }
383
TEST_F(ClientChannelFactoryTest,CloseOnConnect)384 TEST_F(ClientChannelFactoryTest, CloseOnConnect) {
385 client_->Close(ESHUTDOWN);
386
387 EXPECT_CALL(*client_, OnConnect()).WillOnce(Invoke([this] {
388 client_->Close(EIO);
389 }));
390 auto status = client_->SendImpulse(17);
391 ASSERT_FALSE(status);
392 EXPECT_EQ(EIO, status.error());
393 EXPECT_FALSE(client_->IsConnected());
394 EXPECT_EQ(-EIO, client_->error());
395 }
396
TEST_F(ClientChannelFactoryTest,DisableAutoReconnect)397 TEST_F(ClientChannelFactoryTest, DisableAutoReconnect) {
398 client_->Close(EIO);
399 ASSERT_FALSE(client_->IsConnected());
400 client_->DisableAutoReconnect();
401 auto status = client_->SendImpulse(17);
402 ASSERT_FALSE(status);
403 EXPECT_EQ(ESHUTDOWN, status.error());
404 EXPECT_FALSE(client_->IsConnected());
405 client_->EnableAutoReconnect(kTimeout);
406 EXPECT_CALL(*client_, OnConnect());
407 OnConnectCallback([](auto* mock) {
408 EXPECT_CALL(*mock, SendImpulse(17, nullptr, 0))
409 .WillOnce(Return(Status<void>{}));
410 });
411 ASSERT_TRUE(client_->SendImpulse(17));
412 EXPECT_TRUE(client_->IsConnected());
413 }
414
TEST_F(ClientTransactionTest,SendNoData)415 TEST_F(ClientTransactionTest, SendNoData) {
416 void* const kTransactionState = IntToPtr(123);
417 EXPECT_CALL(*mock_channel(), AllocateTransactionState())
418 .WillOnce(Return(kTransactionState));
419 EXPECT_CALL(*mock_channel(), FreeTransactionState(kTransactionState));
420 EXPECT_CALL(*mock_channel(),
421 SendWithInt(kTransactionState, 1, nullptr, 0, nullptr, 0))
422 .WillOnce(Return(0));
423 EXPECT_TRUE(transaction_.Send<void>(1));
424 EXPECT_CALL(*mock_channel(),
425 SendWithFileHandle(kTransactionState, 2, nullptr, 0, nullptr, 0))
426 .WillOnce(Return(ByMove(LocalHandle{-1})));
427 EXPECT_TRUE(transaction_.Send<LocalHandle>(2));
428 EXPECT_CALL(*mock_channel(), SendWithChannelHandle(kTransactionState, 3,
429 nullptr, 0, nullptr, 0))
430 .WillOnce(Return(ByMove(LocalChannelHandle{nullptr, 1})));
431 EXPECT_TRUE(transaction_.Send<LocalChannelHandle>(3));
432 }
433
TEST_F(ClientTransactionTest,SendNoState)434 TEST_F(ClientTransactionTest, SendNoState) {
435 EXPECT_CALL(*mock_channel(), AllocateTransactionState())
436 .WillOnce(Return(nullptr));
437 EXPECT_CALL(*mock_channel(), SendWithInt(nullptr, 1, nullptr, 0, nullptr, 0))
438 .WillOnce(Return(0));
439 EXPECT_CALL(*mock_channel(), FreeTransactionState(nullptr));
440 EXPECT_TRUE(transaction_.Send<void>(1));
441 }
442
TEST_F(ClientTransactionTest,SendBuffers)443 TEST_F(ClientTransactionTest, SendBuffers) {
444 const void* const kSendBuffer = IntToConstPtr(123);
445 const size_t kSendSize = 12;
446 void* const kReceiveBuffer = IntToPtr(456);
447 const size_t kReceiveSize = 34;
448
449 EXPECT_CALL(*mock_channel(), AllocateTransactionState())
450 .WillOnce(Return(nullptr));
451 EXPECT_CALL(*mock_channel(), FreeTransactionState(nullptr));
452
453 EXPECT_CALL(*mock_channel(), SendWithInt(nullptr, 1, nullptr, 0, nullptr, 0))
454 .WillOnce(Return(0));
455 EXPECT_TRUE(transaction_.Send<void>(1, nullptr, 0, nullptr, 0));
456
457 EXPECT_CALL(*mock_channel(),
458 SendWithInt(nullptr, 2, Ne(nullptr), 1, nullptr, 0))
459 .WillOnce(Return(0));
460 EXPECT_TRUE(transaction_.Send<void>(2, kSendBuffer, kSendSize, nullptr, 0));
461
462 EXPECT_CALL(*mock_channel(), SendWithInt(nullptr, 3, nullptr, 0, nullptr, 0))
463 .WillOnce(Return(0));
464 EXPECT_TRUE(transaction_.Send<void>(3, kSendBuffer, 0, nullptr, 0));
465
466 EXPECT_CALL(*mock_channel(),
467 SendWithInt(nullptr, 4, nullptr, 0, Ne(nullptr), 1))
468 .WillOnce(Return(0));
469 EXPECT_TRUE(
470 transaction_.Send<void>(4, nullptr, 0, kReceiveBuffer, kReceiveSize));
471
472 EXPECT_CALL(*mock_channel(), SendWithInt(nullptr, 5, nullptr, 0, nullptr, 0))
473 .WillOnce(Return(0));
474 EXPECT_TRUE(transaction_.Send<void>(5, nullptr, 0, kReceiveBuffer, 0));
475
476 EXPECT_CALL(*mock_channel(),
477 SendWithInt(nullptr, 5, Ne(nullptr), 1, Ne(nullptr), 1))
478 .WillOnce(Return(0));
479 EXPECT_TRUE(transaction_.Send<void>(5, kSendBuffer, kSendSize, kReceiveBuffer,
480 kReceiveSize));
481 }
482
TEST_F(ClientTransactionTest,SendVector)483 TEST_F(ClientTransactionTest, SendVector) {
484 iovec send[3] = {};
485 iovec recv[4] = {};
486
487 EXPECT_CALL(*mock_channel(), AllocateTransactionState())
488 .WillOnce(Return(nullptr));
489 EXPECT_CALL(*mock_channel(), FreeTransactionState(nullptr));
490
491 EXPECT_CALL(*mock_channel(), SendWithInt(nullptr, 1, nullptr, 0, nullptr, 0))
492 .WillOnce(Return(0));
493 EXPECT_TRUE(transaction_.SendVector<void>(1, nullptr, 0, nullptr, 0));
494
495 EXPECT_CALL(*mock_channel(), SendWithInt(nullptr, 2, send, 3, recv, 4))
496 .WillOnce(Return(0));
497 EXPECT_TRUE(transaction_.SendVector<void>(2, send, 3, recv, 4));
498
499 EXPECT_CALL(*mock_channel(), SendWithInt(nullptr, 3, send, 3, nullptr, 0))
500 .WillOnce(Return(0));
501 EXPECT_TRUE(transaction_.SendVector<void>(3, send, nullptr));
502
503 EXPECT_CALL(*mock_channel(), SendWithInt(nullptr, 4, nullptr, 0, recv, 4))
504 .WillOnce(Return(0));
505 EXPECT_TRUE(transaction_.SendVector<void>(4, nullptr, recv));
506
507 EXPECT_CALL(*mock_channel(), SendWithInt(nullptr, 5, send, 3, recv, 4))
508 .WillOnce(Return(0));
509 EXPECT_TRUE(transaction_.SendVector<void>(5, send, recv));
510 }
511
TEST_F(ClientTransactionTest,PushHandle)512 TEST_F(ClientTransactionTest, PushHandle) {
513 void* const kTransactionState = IntToPtr(123);
514 EXPECT_CALL(*mock_channel(), AllocateTransactionState())
515 .WillOnce(Return(kTransactionState));
516 EXPECT_CALL(*mock_channel(), FreeTransactionState(kTransactionState));
517
518 EXPECT_CALL(*mock_channel(),
519 PushFileHandle(kTransactionState, A<const LocalHandle&>()))
520 .WillOnce(Return(1));
521 EXPECT_EQ(1, transaction_.PushFileHandle(LocalHandle{-1}).get());
522
523 EXPECT_CALL(*mock_channel(),
524 PushFileHandle(kTransactionState, A<const BorrowedHandle&>()))
525 .WillOnce(Return(2));
526 EXPECT_EQ(2, transaction_.PushFileHandle(BorrowedHandle{-1}).get());
527
528 EXPECT_EQ(3, transaction_.PushFileHandle(RemoteHandle{3}).get());
529
530 EXPECT_CALL(
531 *mock_channel(),
532 PushChannelHandle(kTransactionState, A<const LocalChannelHandle&>()))
533 .WillOnce(Return(11));
534 EXPECT_EQ(
535 11, transaction_.PushChannelHandle(LocalChannelHandle{nullptr, 1}).get());
536
537 EXPECT_CALL(
538 *mock_channel(),
539 PushChannelHandle(kTransactionState, A<const BorrowedChannelHandle&>()))
540 .WillOnce(Return(12));
541 EXPECT_EQ(12, transaction_.PushChannelHandle(BorrowedChannelHandle{2}).get());
542
543 EXPECT_EQ(13, transaction_.PushChannelHandle(RemoteChannelHandle{13}).get());
544 }
545
TEST_F(ClientTransactionTest,GetHandle)546 TEST_F(ClientTransactionTest, GetHandle) {
547 void* const kTransactionState = IntToPtr(123);
548 EXPECT_CALL(*mock_channel(), AllocateTransactionState())
549 .WillOnce(Return(kTransactionState));
550 EXPECT_CALL(*mock_channel(), FreeTransactionState(kTransactionState));
551
552 EXPECT_CALL(*mock_channel(), GetFileHandle(kTransactionState, 1, _))
553 .WillOnce(Return(false))
554 .WillOnce(Return(true));
555
556 LocalHandle file_handle;
557 EXPECT_FALSE(transaction_.GetFileHandle(1, &file_handle));
558 EXPECT_TRUE(transaction_.GetFileHandle(1, &file_handle));
559
560 EXPECT_CALL(*mock_channel(), GetChannelHandle(kTransactionState, 2, _))
561 .WillOnce(Return(false))
562 .WillOnce(Return(true));
563
564 LocalChannelHandle channel_handle;
565 EXPECT_FALSE(transaction_.GetChannelHandle(2, &channel_handle));
566 EXPECT_TRUE(transaction_.GetChannelHandle(2, &channel_handle));
567 }
568