blob: fc0c8dbbf94f730e84df881d95826b268a9a60b5 [file] [log] [blame]
Alex Vakulenkoe4eec202017-01-27 14:41:04 -08001#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}