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