Home | History | Annotate | Download | only in libpdx
      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