1#include <pdx/service.h>
2
3#include <memory>
4#include <string>
5
6#include <gmock/gmock.h>
7#include <pdx/mock_service_endpoint.h>
8
9using android::pdx::BorrowedChannelHandle;
10using android::pdx::BorrowedHandle;
11using android::pdx::Channel;
12using android::pdx::ChannelReference;
13using android::pdx::ErrorStatus;
14using android::pdx::FileReference;
15using android::pdx::LocalChannelHandle;
16using android::pdx::LocalHandle;
17using android::pdx::Message;
18using android::pdx::MessageInfo;
19using android::pdx::MockEndpoint;
20using android::pdx::RemoteChannelHandle;
21using android::pdx::RemoteHandle;
22using android::pdx::Service;
23using android::pdx::Status;
24
25using testing::A;
26using testing::ByMove;
27using testing::DoAll;
28using testing::Invoke;
29using testing::Matcher;
30using testing::Ref;
31using testing::Return;
32using testing::SetArgPointee;
33using testing::WithArg;
34using testing::WithoutArgs;
35using testing::_;
36
37namespace {
38
39// Helper functions to construct fake void pointers for tests.
40inline void* IntToPtr(intptr_t addr) { return reinterpret_cast<void*>(addr); }
41
42// Helper matchers for working with iovec structures in tests.
43// Simple matcher for one element iovec array:
44// EXPECT_CALL(mock, method(IoVecMatcher(ptr, size)));
45MATCHER_P2(IoVecMatcher, ptr, size, "") {
46  return arg->iov_base == ptr && arg->iov_len == size;
47}
48
49// Matcher for an array of iovecs:
50// EXPECT_CALL(mock,
51//             method(IoVecMatcher(IoVecArray{{ptr1, size1}, {ptr2, size2}})));
52using IoVecArray = std::vector<iovec>;
53MATCHER_P(IoVecMatcher, iovec_array, "") {
54  for (const iovec& item : iovec_array) {
55    if (arg->iov_base != item.iov_base || arg->iov_len != item.iov_len)
56      return false;
57    arg++;
58  }
59  return true;
60}
61
62using IoVecData = std::vector<std::string>;
63MATCHER_P(IoVecDataMatcher, iovec_data, "") {
64  for (const std::string& item : iovec_data) {
65    std::string data{reinterpret_cast<const char*>(arg->iov_base),
66                     arg->iov_len};
67    if (data != item)
68      return false;
69    arg++;
70  }
71  return true;
72}
73
74MATCHER_P(FileHandleMatcher, value, "") { return arg.Get() == value; }
75MATCHER_P(ChannelHandleMatcher, value, "") { return arg.value() == value; }
76
77enum : int {
78  kTestPid = 1,
79  kTestTid,
80  kTestCid,
81  kTestMid,
82  kTestEuid,
83  kTestEgid,
84  kTestOp,
85};
86
87class MockService : public Service {
88 public:
89  using Service::Service;
90  MOCK_METHOD1(OnChannelOpen, std::shared_ptr<Channel>(Message& message));
91  MOCK_METHOD2(OnChannelClose,
92               void(Message& message, const std::shared_ptr<Channel>& channel));
93  MOCK_METHOD1(HandleMessage, Status<void>(Message& message));
94  MOCK_METHOD1(HandleImpulse, void(Message& impulse));
95  MOCK_METHOD0(OnSysPropChange, void());
96  MOCK_METHOD1(DumpState, std::string(size_t max_length));
97};
98
99class ServiceTest : public testing::Test {
100 public:
101  ServiceTest() {
102    auto endpoint = std::make_unique<testing::StrictMock<MockEndpoint>>();
103    EXPECT_CALL(*endpoint, SetService(_))
104        .Times(2)
105        .WillRepeatedly(Return(Status<void>{}));
106    service_ = std::make_shared<MockService>("MockSvc", std::move(endpoint));
107  }
108
109  MockEndpoint* endpoint() {
110    return static_cast<MockEndpoint*>(service_->endpoint());
111  }
112
113  void SetupMessageInfo(MessageInfo* info, int32_t op, bool impulse = false) {
114    info->pid = kTestPid;
115    info->tid = kTestTid;
116    info->cid = kTestCid;
117    info->mid = impulse ? Message::IMPULSE_MESSAGE_ID : kTestMid;
118    info->euid = kTestEuid;
119    info->egid = kTestEgid;
120    info->op = op;
121    info->flags = 0;
122    info->service = service_.get();
123    info->channel = nullptr;
124    info->send_len = 0;
125    info->recv_len = 0;
126    info->fd_count = 0;
127    memset(info->impulse, 0, sizeof(info->impulse));
128  }
129
130  void SetupMessageInfoAndDefaultExpectations(MessageInfo* info, int32_t op,
131                                              bool impulse = false) {
132    SetupMessageInfo(info, op, impulse);
133    EXPECT_CALL(*endpoint(), AllocateMessageState()).WillOnce(Return(kState));
134    EXPECT_CALL(*endpoint(), FreeMessageState(kState));
135  }
136
137  void ExpectDefaultHandleMessage() {
138    EXPECT_CALL(*endpoint(), MessageReply(_, -EOPNOTSUPP))
139        .WillOnce(Return(Status<void>{}));
140  }
141
142  std::shared_ptr<MockService> service_;
143  void* kState = IntToPtr(123456);
144};
145
146class ServiceMessageTest : public ServiceTest {
147 public:
148  ServiceMessageTest() {
149    MessageInfo info;
150    SetupMessageInfoAndDefaultExpectations(&info, kTestOp);
151    message_ = std::make_unique<Message>(info);
152  }
153
154  std::unique_ptr<Message> message_;
155};
156
157}  // anonymous namespace
158
159///////////////////////////////////////////////////////////////////////////////
160// Service class tests
161///////////////////////////////////////////////////////////////////////////////
162
163TEST_F(ServiceTest, IsInitialized) {
164  EXPECT_TRUE(service_->IsInitialized());
165  service_ = std::make_shared<MockService>("MockSvc2", nullptr);
166  EXPECT_FALSE(service_->IsInitialized());
167}
168
169TEST_F(ServiceTest, ConstructMessage) {
170  MessageInfo info;
171  SetupMessageInfo(&info, kTestOp);
172  auto test_channel = std::make_shared<Channel>();
173  info.channel = test_channel.get();
174  EXPECT_CALL(*endpoint(), AllocateMessageState()).WillOnce(Return(kState));
175
176  Message message{info};
177
178  EXPECT_FALSE(message.IsImpulse());
179  EXPECT_EQ(kTestPid, message.GetProcessId());
180  EXPECT_EQ(kTestTid, message.GetThreadId());
181  EXPECT_EQ(kTestCid, message.GetChannelId());
182  EXPECT_EQ(kTestMid, message.GetMessageId());
183  EXPECT_EQ(kTestEuid, message.GetEffectiveUserId());
184  EXPECT_EQ(kTestEgid, message.GetEffectiveGroupId());
185  EXPECT_EQ(kTestOp, message.GetOp());
186  EXPECT_EQ(service_, message.GetService());
187  EXPECT_EQ(test_channel, message.GetChannel());
188  EXPECT_FALSE(message.replied());
189  EXPECT_FALSE(message.IsChannelExpired());
190  EXPECT_FALSE(message.IsServiceExpired());
191  EXPECT_EQ(kState, message.GetState());
192
193  ExpectDefaultHandleMessage();
194  EXPECT_CALL(*endpoint(), FreeMessageState(kState));
195}
196
197TEST_F(ServiceTest, ConstructImpulseMessage) {
198  MessageInfo info;
199  SetupMessageInfo(&info, kTestOp, true);
200  auto test_channel = std::make_shared<Channel>();
201  info.channel = test_channel.get();
202  EXPECT_CALL(*endpoint(), AllocateMessageState()).WillOnce(Return(nullptr));
203
204  Message message{info};
205
206  EXPECT_TRUE(message.IsImpulse());
207  EXPECT_EQ(kTestOp, message.GetOp());
208  EXPECT_EQ(service_, message.GetService());
209  EXPECT_EQ(test_channel, message.GetChannel());
210  EXPECT_TRUE(message.replied());
211  EXPECT_FALSE(message.IsChannelExpired());
212  EXPECT_FALSE(message.IsServiceExpired());
213
214  // DefaultHandleMessage should not be called here.
215  EXPECT_CALL(*endpoint(), FreeMessageState(nullptr));
216}
217
218TEST_F(ServiceTest, HandleMessageChannelOpen) {
219  MessageInfo info;
220  SetupMessageInfoAndDefaultExpectations(&info,
221                                         android::pdx::opcodes::CHANNEL_OPEN);
222  Message message{info};
223
224  auto channel = std::make_shared<Channel>();
225  EXPECT_CALL(*service_, OnChannelOpen(Ref(message))).WillOnce(Return(channel));
226  EXPECT_CALL(*endpoint(), SetChannel(kTestCid, channel.get()))
227      .WillOnce(Return(Status<void>{}));
228  EXPECT_CALL(*endpoint(), MessageReply(&message, 0))
229      .WillOnce(Return(Status<void>{}));
230
231  EXPECT_TRUE(service_->Service::HandleMessage(message));
232}
233
234TEST_F(ServiceTest, HandleMessageChannelClose) {
235  MessageInfo info;
236  SetupMessageInfoAndDefaultExpectations(&info,
237                                         android::pdx::opcodes::CHANNEL_CLOSE);
238  auto channel = std::make_shared<Channel>();
239  info.channel = channel.get();
240  Message message{info};
241
242  EXPECT_CALL(*service_, OnChannelClose(Ref(message), channel));
243  EXPECT_CALL(*endpoint(), SetChannel(kTestCid, nullptr))
244      .WillOnce(Return(Status<void>{}));
245  EXPECT_CALL(*endpoint(), MessageReply(&message, 0))
246      .WillOnce(Return(Status<void>{}));
247
248  EXPECT_TRUE(service_->Service::HandleMessage(message));
249}
250
251TEST_F(ServiceTest, HandleMessageOnSysPropChange) {
252  MessageInfo info;
253  SetupMessageInfoAndDefaultExpectations(
254      &info, android::pdx::opcodes::REPORT_SYSPROP_CHANGE);
255  Message message{info};
256
257  EXPECT_CALL(*service_, OnSysPropChange());
258  EXPECT_CALL(*endpoint(), MessageReply(&message, 0))
259      .WillOnce(Return(Status<void>{}));
260
261  EXPECT_TRUE(service_->Service::HandleMessage(message));
262}
263
264TEST_F(ServiceTest, HandleMessageOnDumpState) {
265  const size_t kRecvBufSize = 1000;
266  MessageInfo info;
267  SetupMessageInfoAndDefaultExpectations(&info,
268                                         android::pdx::opcodes::DUMP_STATE);
269  info.recv_len = kRecvBufSize;
270  Message message{info};
271
272  const std::string kReply = "foo";
273  EXPECT_CALL(*service_, DumpState(kRecvBufSize)).WillOnce(Return(kReply));
274  EXPECT_CALL(
275      *endpoint(),
276      WriteMessageData(&message, IoVecDataMatcher(IoVecData{kReply}), 1))
277      .WillOnce(Return(kReply.size()));
278  EXPECT_CALL(*endpoint(), MessageReply(&message, kReply.size()))
279      .WillOnce(Return(Status<void>{}));
280
281  EXPECT_TRUE(service_->Service::HandleMessage(message));
282}
283
284TEST_F(ServiceTest, HandleMessageOnDumpStateTooLarge) {
285  const size_t kRecvBufSize = 3;
286  MessageInfo info;
287  SetupMessageInfoAndDefaultExpectations(&info,
288                                         android::pdx::opcodes::DUMP_STATE);
289  info.recv_len = kRecvBufSize;
290  Message message{info};
291
292  const std::string kReply = "0123456789";
293  const std::string kActualReply = kReply.substr(0, kRecvBufSize);
294  EXPECT_CALL(*service_, DumpState(kRecvBufSize)).WillOnce(Return(kReply));
295  EXPECT_CALL(
296      *endpoint(),
297      WriteMessageData(&message, IoVecDataMatcher(IoVecData{kActualReply}), 1))
298      .WillOnce(Return(kActualReply.size()));
299  EXPECT_CALL(*endpoint(), MessageReply(&message, kActualReply.size()))
300      .WillOnce(Return(Status<void>{}));
301
302  EXPECT_TRUE(service_->Service::HandleMessage(message));
303}
304
305TEST_F(ServiceTest, HandleMessageOnDumpStateFail) {
306  const size_t kRecvBufSize = 1000;
307  MessageInfo info;
308  SetupMessageInfoAndDefaultExpectations(&info,
309                                         android::pdx::opcodes::DUMP_STATE);
310  info.recv_len = kRecvBufSize;
311  Message message{info};
312
313  const std::string kReply = "foo";
314  EXPECT_CALL(*service_, DumpState(kRecvBufSize)).WillOnce(Return(kReply));
315  EXPECT_CALL(
316      *endpoint(),
317      WriteMessageData(&message, IoVecDataMatcher(IoVecData{kReply}), 1))
318      .WillOnce(Return(1));
319  EXPECT_CALL(*endpoint(), MessageReply(&message, -EIO))
320      .WillOnce(Return(Status<void>{}));
321
322  EXPECT_TRUE(service_->Service::HandleMessage(message));
323}
324
325TEST_F(ServiceTest, HandleMessageCustom) {
326  MessageInfo info;
327  SetupMessageInfoAndDefaultExpectations(&info, kTestOp);
328  Message message{info};
329
330  EXPECT_CALL(*endpoint(), MessageReply(&message, -EOPNOTSUPP))
331      .WillOnce(Return(Status<void>{}));
332
333  EXPECT_TRUE(service_->Service::HandleMessage(message));
334}
335
336TEST_F(ServiceTest, ReplyMessageWithoutService) {
337  MessageInfo info;
338  SetupMessageInfo(&info, kTestOp);
339  EXPECT_CALL(*endpoint(), AllocateMessageState()).WillOnce(Return(nullptr));
340
341  Message message{info};
342
343  EXPECT_FALSE(message.IsServiceExpired());
344  service_.reset();
345  EXPECT_TRUE(message.IsServiceExpired());
346
347  EXPECT_EQ(EINVAL, message.Reply(12).error());
348}
349
350TEST_F(ServiceTest, ReceiveAndDispatchMessage) {
351  MessageInfo info;
352  SetupMessageInfoAndDefaultExpectations(&info, kTestOp);
353  ExpectDefaultHandleMessage();
354
355  auto on_receive = [&info](Message* message) -> Status<void> {
356    *message = Message{info};
357    return {};
358  };
359  EXPECT_CALL(*endpoint(), MessageReceive(_)).WillOnce(Invoke(on_receive));
360  EXPECT_CALL(*service_, HandleMessage(_)).WillOnce(Return(Status<void>{}));
361
362  EXPECT_TRUE(service_->ReceiveAndDispatch());
363}
364
365TEST_F(ServiceTest, ReceiveAndDispatchImpulse) {
366  MessageInfo info;
367  SetupMessageInfoAndDefaultExpectations(&info, kTestOp, true);
368
369  auto on_receive = [&info](Message* message) -> Status<void> {
370    *message = Message{info};
371    return {};
372  };
373  EXPECT_CALL(*endpoint(), MessageReceive(_)).WillOnce(Invoke(on_receive));
374  EXPECT_CALL(*service_, HandleImpulse(_));
375
376  EXPECT_TRUE(service_->ReceiveAndDispatch());
377}
378
379TEST_F(ServiceTest, Cancel) {
380  EXPECT_CALL(*endpoint(), Cancel()).WillOnce(Return(Status<void>{}));
381  EXPECT_TRUE(service_->Cancel());
382}
383
384///////////////////////////////////////////////////////////////////////////////
385// Message class tests
386///////////////////////////////////////////////////////////////////////////////
387
388TEST_F(ServiceMessageTest, Reply) {
389  EXPECT_CALL(*endpoint(), MessageReply(message_.get(), 12))
390      .WillOnce(Return(Status<void>{}));
391  EXPECT_FALSE(message_->replied());
392  EXPECT_TRUE(message_->Reply(12));
393  EXPECT_TRUE(message_->replied());
394
395  EXPECT_EQ(EINVAL, message_->Reply(12).error());  // Already replied.
396}
397
398TEST_F(ServiceMessageTest, ReplyFail) {
399  EXPECT_CALL(*endpoint(), MessageReply(message_.get(), 12))
400      .WillOnce(Return(ErrorStatus{EIO}));
401  EXPECT_EQ(EIO, message_->Reply(12).error());
402
403  ExpectDefaultHandleMessage();
404}
405
406TEST_F(ServiceMessageTest, ReplyError) {
407  EXPECT_CALL(*endpoint(), MessageReply(message_.get(), -12))
408      .WillOnce(Return(Status<void>{}));
409  EXPECT_TRUE(message_->ReplyError(12));
410}
411
412TEST_F(ServiceMessageTest, ReplyFileDescriptor) {
413  EXPECT_CALL(*endpoint(), MessageReplyFd(message_.get(), 5))
414      .WillOnce(Return(Status<void>{}));
415  EXPECT_TRUE(message_->ReplyFileDescriptor(5));
416}
417
418TEST_F(ServiceMessageTest, ReplyLocalFileHandle) {
419  const int kFakeFd = 12345;
420  LocalHandle handle{kFakeFd};
421  EXPECT_CALL(*endpoint(), MessageReplyFd(message_.get(), kFakeFd))
422      .WillOnce(Return(Status<void>{}));
423  EXPECT_TRUE(message_->Reply(handle));
424  handle.Release();  // Make sure we do not close the fake file descriptor.
425}
426
427TEST_F(ServiceMessageTest, ReplyLocalFileHandleError) {
428  LocalHandle handle{-EINVAL};
429  EXPECT_CALL(*endpoint(), MessageReply(message_.get(), -EINVAL))
430      .WillOnce(Return(Status<void>{}));
431  EXPECT_TRUE(message_->Reply(handle));
432}
433
434TEST_F(ServiceMessageTest, ReplyBorrowedFileHandle) {
435  const int kFakeFd = 12345;
436  BorrowedHandle handle{kFakeFd};
437  EXPECT_CALL(*endpoint(), MessageReplyFd(message_.get(), kFakeFd))
438      .WillOnce(Return(Status<void>{}));
439  EXPECT_TRUE(message_->Reply(handle));
440}
441
442TEST_F(ServiceMessageTest, ReplyBorrowedFileHandleError) {
443  BorrowedHandle handle{-EACCES};
444  EXPECT_CALL(*endpoint(), MessageReply(message_.get(), -EACCES))
445      .WillOnce(Return(Status<void>{}));
446  EXPECT_TRUE(message_->Reply(handle));
447}
448
449TEST_F(ServiceMessageTest, ReplyRemoteFileHandle) {
450  RemoteHandle handle{123};
451  EXPECT_CALL(*endpoint(), MessageReply(message_.get(), handle.Get()))
452      .WillOnce(Return(Status<void>{}));
453  EXPECT_TRUE(message_->Reply(handle));
454}
455
456TEST_F(ServiceMessageTest, ReplyRemoteFileHandleError) {
457  RemoteHandle handle{-EIO};
458  EXPECT_CALL(*endpoint(), MessageReply(message_.get(), -EIO))
459      .WillOnce(Return(Status<void>{}));
460  EXPECT_TRUE(message_->Reply(handle));
461}
462
463TEST_F(ServiceMessageTest, ReplyLocalChannelHandle) {
464  LocalChannelHandle handle{nullptr, 12345};
465  EXPECT_CALL(*endpoint(), MessageReplyChannelHandle(
466                               message_.get(), A<const LocalChannelHandle&>()))
467      .WillOnce(Return(Status<void>{}));
468  EXPECT_TRUE(message_->Reply(handle));
469}
470
471TEST_F(ServiceMessageTest, ReplyBorrowedChannelHandle) {
472  BorrowedChannelHandle handle{12345};
473  EXPECT_CALL(*endpoint(),
474              MessageReplyChannelHandle(message_.get(),
475                                        A<const BorrowedChannelHandle&>()))
476      .WillOnce(Return(Status<void>{}));
477  EXPECT_TRUE(message_->Reply(handle));
478}
479
480TEST_F(ServiceMessageTest, ReplyRemoteChannelHandle) {
481  RemoteChannelHandle handle{12345};
482  EXPECT_CALL(*endpoint(), MessageReplyChannelHandle(
483                               message_.get(), A<const RemoteChannelHandle&>()))
484      .WillOnce(Return(Status<void>{}));
485  EXPECT_TRUE(message_->Reply(handle));
486}
487
488TEST_F(ServiceMessageTest, ReplyStatusInt) {
489  Status<int> status{123};
490  EXPECT_CALL(*endpoint(), MessageReply(message_.get(), status.get()))
491      .WillOnce(Return(Status<void>{}));
492  EXPECT_TRUE(message_->Reply(status));
493}
494
495TEST_F(ServiceMessageTest, ReplyStatusError) {
496  Status<int> status{ErrorStatus{EIO}};
497  EXPECT_CALL(*endpoint(), MessageReply(message_.get(), -status.error()))
498      .WillOnce(Return(Status<void>{}));
499  EXPECT_TRUE(message_->Reply(status));
500}
501
502TEST_F(ServiceMessageTest, Read) {
503  ExpectDefaultHandleMessage();
504  void* const kDataBuffer = IntToPtr(12345);
505  const size_t kDataSize = 100;
506  EXPECT_CALL(
507      *endpoint(),
508      ReadMessageData(message_.get(), IoVecMatcher(kDataBuffer, kDataSize), 1))
509      .WillOnce(Return(50))
510      .WillOnce(Return(ErrorStatus{EACCES}));
511  EXPECT_EQ(50u, message_->Read(kDataBuffer, kDataSize).get());
512  EXPECT_EQ(EACCES, message_->Read(kDataBuffer, kDataSize).error());
513}
514
515TEST_F(ServiceMessageTest, ReadVector) {
516  ExpectDefaultHandleMessage();
517  char buffer1[10];
518  char buffer2[20];
519  iovec vec[] = {{buffer1, sizeof(buffer1)}, {buffer2, sizeof(buffer2)}};
520  EXPECT_CALL(*endpoint(),
521              ReadMessageData(
522                  message_.get(),
523                  IoVecMatcher(IoVecArray{std::begin(vec), std::end(vec)}), 2))
524      .WillOnce(Return(30))
525      .WillOnce(Return(15))
526      .WillOnce(Return(ErrorStatus{EBADF}));
527  EXPECT_EQ(30u, message_->ReadVector(vec, 2).get());
528  EXPECT_EQ(15u, message_->ReadVector(vec).get());
529  EXPECT_EQ(EBADF, message_->ReadVector(vec).error());
530}
531
532TEST_F(ServiceMessageTest, Write) {
533  ExpectDefaultHandleMessage();
534  void* const kDataBuffer = IntToPtr(12345);
535  const size_t kDataSize = 100;
536  EXPECT_CALL(
537      *endpoint(),
538      WriteMessageData(message_.get(), IoVecMatcher(kDataBuffer, kDataSize), 1))
539      .WillOnce(Return(50))
540      .WillOnce(Return(ErrorStatus{EBADMSG}));
541  EXPECT_EQ(50u, message_->Write(kDataBuffer, kDataSize).get());
542  EXPECT_EQ(EBADMSG, message_->Write(kDataBuffer, kDataSize).error());
543}
544
545TEST_F(ServiceMessageTest, WriteVector) {
546  ExpectDefaultHandleMessage();
547  char buffer1[10];
548  char buffer2[20];
549  iovec vec[] = {{buffer1, sizeof(buffer1)}, {buffer2, sizeof(buffer2)}};
550  EXPECT_CALL(*endpoint(),
551              WriteMessageData(
552                  message_.get(),
553                  IoVecMatcher(IoVecArray{std::begin(vec), std::end(vec)}), 2))
554      .WillOnce(Return(30))
555      .WillOnce(Return(15))
556      .WillOnce(Return(ErrorStatus{EIO}));
557  EXPECT_EQ(30u, message_->WriteVector(vec, 2).get());
558  EXPECT_EQ(15u, message_->WriteVector(vec).get());
559  EXPECT_EQ(EIO, message_->WriteVector(vec, 2).error());
560}
561
562TEST_F(ServiceMessageTest, PushLocalFileHandle) {
563  ExpectDefaultHandleMessage();
564  const int kFakeFd = 12345;
565  LocalHandle handle{kFakeFd};
566  EXPECT_CALL(*endpoint(),
567              PushFileHandle(message_.get(), Matcher<const LocalHandle&>(
568                                                 FileHandleMatcher(kFakeFd))))
569      .WillOnce(Return(12))
570      .WillOnce(Return(ErrorStatus{EIO}));
571  EXPECT_EQ(12, message_->PushFileHandle(handle).get());
572  EXPECT_EQ(EIO, message_->PushFileHandle(handle).error());
573  handle.Release();  // Make sure we do not close the fake file descriptor.
574}
575
576TEST_F(ServiceMessageTest, PushBorrowedFileHandle) {
577  ExpectDefaultHandleMessage();
578  const int kFakeFd = 12345;
579  BorrowedHandle handle{kFakeFd};
580  EXPECT_CALL(*endpoint(),
581              PushFileHandle(message_.get(), Matcher<const BorrowedHandle&>(
582                                                 FileHandleMatcher(kFakeFd))))
583      .WillOnce(Return(13))
584      .WillOnce(Return(ErrorStatus{EACCES}));
585  EXPECT_EQ(13, message_->PushFileHandle(handle).get());
586  EXPECT_EQ(EACCES, message_->PushFileHandle(handle).error());
587}
588
589TEST_F(ServiceMessageTest, PushRemoteFileHandle) {
590  ExpectDefaultHandleMessage();
591  const int kFakeFd = 12345;
592  RemoteHandle handle{kFakeFd};
593  EXPECT_CALL(*endpoint(),
594              PushFileHandle(message_.get(), Matcher<const RemoteHandle&>(
595                                                 FileHandleMatcher(kFakeFd))))
596      .WillOnce(Return(kFakeFd))
597      .WillOnce(Return(ErrorStatus{EIO}));
598  EXPECT_EQ(kFakeFd, message_->PushFileHandle(handle).get());
599  EXPECT_EQ(EIO, message_->PushFileHandle(handle).error());
600}
601
602TEST_F(ServiceMessageTest, PushLocalChannelHandle) {
603  ExpectDefaultHandleMessage();
604  int32_t kValue = 12345;
605  LocalChannelHandle handle{nullptr, kValue};
606  EXPECT_CALL(*endpoint(), PushChannelHandle(message_.get(),
607                                             Matcher<const LocalChannelHandle&>(
608                                                 ChannelHandleMatcher(kValue))))
609      .WillOnce(Return(7))
610      .WillOnce(Return(ErrorStatus{EIO}));
611  EXPECT_EQ(7, message_->PushChannelHandle(handle).get());
612  EXPECT_EQ(EIO, message_->PushChannelHandle(handle).error());
613}
614
615TEST_F(ServiceMessageTest, PushBorrowedChannelHandle) {
616  ExpectDefaultHandleMessage();
617  int32_t kValue = 12345;
618  BorrowedChannelHandle handle{kValue};
619  EXPECT_CALL(
620      *endpoint(),
621      PushChannelHandle(message_.get(), Matcher<const BorrowedChannelHandle&>(
622                                            ChannelHandleMatcher(kValue))))
623      .WillOnce(Return(8))
624      .WillOnce(Return(ErrorStatus{EIO}));
625  EXPECT_EQ(8, message_->PushChannelHandle(handle).get());
626  EXPECT_EQ(EIO, message_->PushChannelHandle(handle).error());
627}
628
629TEST_F(ServiceMessageTest, PushRemoteChannelHandle) {
630  ExpectDefaultHandleMessage();
631  int32_t kValue = 12345;
632  RemoteChannelHandle handle{kValue};
633  EXPECT_CALL(
634      *endpoint(),
635      PushChannelHandle(message_.get(), Matcher<const RemoteChannelHandle&>(
636                                            ChannelHandleMatcher(kValue))))
637      .WillOnce(Return(kValue))
638      .WillOnce(Return(ErrorStatus{EIO}));
639  EXPECT_EQ(kValue, message_->PushChannelHandle(handle).get());
640  EXPECT_EQ(EIO, message_->PushChannelHandle(handle).error());
641}
642
643TEST_F(ServiceMessageTest, GetFileHandle) {
644  ExpectDefaultHandleMessage();
645  auto make_file_handle = [](FileReference ref) { return LocalHandle{ref}; };
646  EXPECT_CALL(*endpoint(), GetFileHandle(message_.get(), _))
647      .WillOnce(WithArg<1>(Invoke(make_file_handle)));
648  LocalHandle handle;
649  FileReference kRef = 12345;
650  EXPECT_TRUE(message_->GetFileHandle(kRef, &handle));
651  EXPECT_EQ(kRef, handle.Get());
652  handle.Release();  // Make sure we do not close the fake file descriptor.
653}
654
655TEST_F(ServiceMessageTest, GetFileHandleInvalid) {
656  ExpectDefaultHandleMessage();
657  LocalHandle handle;
658  FileReference kRef = -12;
659  EXPECT_TRUE(message_->GetFileHandle(kRef, &handle));
660  EXPECT_EQ(kRef, handle.Get());
661}
662
663TEST_F(ServiceMessageTest, GetFileHandleError) {
664  ExpectDefaultHandleMessage();
665  EXPECT_CALL(*endpoint(), GetFileHandle(message_.get(), _))
666      .WillOnce(WithoutArgs(Invoke([] { return LocalHandle{-EIO}; })));
667  LocalHandle handle;
668  FileReference kRef = 12345;
669  EXPECT_FALSE(message_->GetFileHandle(kRef, &handle));
670  EXPECT_EQ(-EIO, handle.Get());
671}
672
673TEST_F(ServiceMessageTest, GetChannelHandle) {
674  ExpectDefaultHandleMessage();
675  auto make_channel_handle = [](ChannelReference ref) {
676    return LocalChannelHandle{nullptr, ref};
677  };
678  EXPECT_CALL(*endpoint(), GetChannelHandle(message_.get(), _))
679      .WillOnce(WithArg<1>(Invoke(make_channel_handle)));
680  LocalChannelHandle handle;
681  ChannelReference kRef = 12345;
682  EXPECT_TRUE(message_->GetChannelHandle(kRef, &handle));
683  EXPECT_EQ(kRef, handle.value());
684}
685
686TEST_F(ServiceMessageTest, GetChannelHandleInvalid) {
687  ExpectDefaultHandleMessage();
688  LocalChannelHandle handle;
689  ChannelReference kRef = -12;
690  EXPECT_TRUE(message_->GetChannelHandle(kRef, &handle));
691  EXPECT_EQ(-12, handle.value());
692}
693
694TEST_F(ServiceMessageTest, GetChannelHandleError) {
695  ExpectDefaultHandleMessage();
696  EXPECT_CALL(*endpoint(), GetChannelHandle(message_.get(), _))
697      .WillOnce(WithoutArgs(Invoke([] {
698        return LocalChannelHandle{nullptr, -EIO};
699      })));
700  LocalChannelHandle handle;
701  ChannelReference kRef = 12345;
702  EXPECT_FALSE(message_->GetChannelHandle(kRef, &handle));
703  EXPECT_EQ(-EIO, handle.value());
704}
705
706TEST_F(ServiceMessageTest, ModifyChannelEvents) {
707  ExpectDefaultHandleMessage();
708  int kClearMask = 1;
709  int kSetMask = 2;
710  EXPECT_CALL(*endpoint(), ModifyChannelEvents(kTestCid, kClearMask, kSetMask))
711      .WillOnce(Return(Status<void>{}));
712  EXPECT_TRUE(message_->ModifyChannelEvents(kClearMask, kSetMask));
713}
714
715TEST_F(ServiceMessageTest, PushChannelSameService) {
716  ExpectDefaultHandleMessage();
717  int kFlags = 123;
718  int32_t kValue = 12;
719  EXPECT_CALL(*endpoint(), PushChannel(message_.get(), kFlags, nullptr, _))
720      .WillOnce(DoAll(SetArgPointee<3>(kTestCid),
721                      Return(ByMove(RemoteChannelHandle{kValue}))));
722  int channel_id = -1;
723  auto status = message_->PushChannel(kFlags, nullptr, &channel_id);
724  ASSERT_TRUE(status);
725  EXPECT_EQ(kValue, status.get().value());
726  EXPECT_EQ(kTestCid, channel_id);
727}
728
729TEST_F(ServiceMessageTest, PushChannelFailure) {
730  ExpectDefaultHandleMessage();
731  int kFlags = 123;
732  EXPECT_CALL(*endpoint(), PushChannel(message_.get(), kFlags, nullptr, _))
733      .WillOnce(Return(ByMove(ErrorStatus{EIO})));
734  int channel_id = -1;
735  auto status = message_->PushChannel(kFlags, nullptr, &channel_id);
736  ASSERT_FALSE(status);
737  EXPECT_EQ(EIO, status.error());
738}
739
740TEST_F(ServiceMessageTest, PushChannelDifferentService) {
741  ExpectDefaultHandleMessage();
742  auto endpoint2 = std::make_unique<testing::StrictMock<MockEndpoint>>();
743  EXPECT_CALL(*endpoint2, SetService(_))
744      .Times(2)
745      .WillRepeatedly(Return(Status<void>{}));
746  auto service2 =
747      std::make_shared<MockService>("MockSvc2", std::move(endpoint2));
748
749  int kFlags = 123;
750  int32_t kValue = 12;
751  EXPECT_CALL(*static_cast<MockEndpoint*>(service2->endpoint()),
752              PushChannel(message_.get(), kFlags, nullptr, _))
753      .WillOnce(DoAll(SetArgPointee<3>(kTestCid),
754                      Return(ByMove(RemoteChannelHandle{kValue}))));
755  int channel_id = -1;
756  auto status =
757      message_->PushChannel(service2.get(), kFlags, nullptr, &channel_id);
758  ASSERT_TRUE(status);
759  EXPECT_EQ(kValue, status.get().value());
760  EXPECT_EQ(kTestCid, channel_id);
761}
762
763TEST_F(ServiceMessageTest, CheckChannelSameService) {
764  ExpectDefaultHandleMessage();
765
766  auto test_channel = std::make_shared<Channel>();
767  ChannelReference kRef = 123;
768  EXPECT_CALL(*endpoint(), CheckChannel(message_.get(), kRef, _))
769      .WillOnce(DoAll(SetArgPointee<2>(test_channel.get()), Return(kTestCid)));
770  std::shared_ptr<Channel> channel;
771  auto status = message_->CheckChannel(kRef, &channel);
772  ASSERT_TRUE(status);
773  EXPECT_EQ(kTestCid, status.get());
774  EXPECT_EQ(test_channel, channel);
775}
776
777TEST_F(ServiceMessageTest, CheckChannelFailure) {
778  ExpectDefaultHandleMessage();
779  ChannelReference kRef = 123;
780  EXPECT_CALL(*endpoint(), CheckChannel(message_.get(), kRef, _))
781      .WillOnce(Return(ByMove(ErrorStatus{EOPNOTSUPP})));
782  std::shared_ptr<Channel> channel;
783  auto status = message_->CheckChannel(kRef, &channel);
784  ASSERT_FALSE(status);
785  EXPECT_EQ(EOPNOTSUPP, status.error());
786}
787
788TEST_F(ServiceMessageTest, CheckChannelDifferentService) {
789  ExpectDefaultHandleMessage();
790  auto endpoint2 = std::make_unique<testing::StrictMock<MockEndpoint>>();
791  EXPECT_CALL(*endpoint2, SetService(_))
792      .Times(2)
793      .WillRepeatedly(Return(Status<void>{}));
794  auto service2 =
795      std::make_shared<MockService>("MockSvc2", std::move(endpoint2));
796
797  auto test_channel = std::make_shared<Channel>();
798  ChannelReference kRef = 123;
799  EXPECT_CALL(*static_cast<MockEndpoint*>(service2->endpoint()),
800              CheckChannel(message_.get(), kRef, _))
801      .WillOnce(DoAll(SetArgPointee<2>(test_channel.get()), Return(kTestCid)));
802  std::shared_ptr<Channel> channel;
803  auto status = message_->CheckChannel(service2.get(), kRef, &channel);
804  ASSERT_TRUE(status);
805  EXPECT_EQ(kTestCid, status.get());
806  EXPECT_EQ(test_channel, channel);
807}
808