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 36 inline void* IntToPtr(intptr_t addr) { return reinterpret_cast<void*>(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: 61 explicit SimpleClient(std::unique_ptr<ClientChannel> channel) 62 : BASE{std::move(channel)} {} 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: 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: 92 ClientChannelTest() 93 : client_{SimpleClient::Create( 94 std::make_unique<testing::StrictMock<MockClientChannel>>())} {} 95 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: 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 113 MockClientChannel* mock_channel() { 114 return static_cast<MockClientChannel*>(client_->GetChannel()); 115 } 116 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 127 void OnConnectCallback(std::function<void(MockClientChannel*)> callback) { 128 on_connect_callback_ = callback; 129 } 130 void SetOnConnectError(int error) { on_connect_error_ = error; } 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: 143 ClientTransactionTest() : transaction_{*client_} {} 144 145 Transaction transaction_; 146 }; 147 148 } // anonymous namespace 149 150 TEST_F(ClientChannelTest, IsInitialized) { 151 ASSERT_NE(client_.get(), nullptr); 152 EXPECT_TRUE(client_->IsInitialized()); 153 EXPECT_TRUE(client_->IsConnected()); 154 } 155 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 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 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 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 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 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 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 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 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 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 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 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 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 334 TEST_F(ClientChannelFactoryTest, IsInitialized) { 335 ASSERT_NE(client_.get(), nullptr); 336 EXPECT_TRUE(client_->IsInitialized()); 337 EXPECT_TRUE(client_->IsConnected()); 338 } 339 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 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 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 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 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 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 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 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 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 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 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