client_tests.cpp 20 KB

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