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