1 #include <errno.h>
2 #include <fcntl.h>
3 #include <poll.h>
4 #include <sys/epoll.h>
5 #include <sys/eventfd.h>
6 #include <unistd.h>
7
8 #include <array>
9 #include <atomic>
10 #include <memory>
11 #include <numeric>
12 #include <string>
13 #include <thread>
14
15 #include <gtest/gtest.h>
16 #include <pdx/channel_handle.h>
17 #include <pdx/client.h>
18 #include <pdx/file_handle.h>
19 #include <pdx/service.h>
20 #include <pdx/service_dispatcher.h>
21 #include <private/android_filesystem_config.h>
22 #include <uds/client_channel.h>
23 #include <uds/client_channel_factory.h>
24 #include <uds/service_endpoint.h>
25
26 using android::pdx::BorrowedChannelHandle;
27 using android::pdx::Channel;
28 using android::pdx::ChannelReference;
29 using android::pdx::ClientBase;
30 using android::pdx::ErrorStatus;
31 using android::pdx::LocalChannelHandle;
32 using android::pdx::LocalHandle;
33 using android::pdx::Message;
34 using android::pdx::MessageInfo;
35 using android::pdx::RemoteChannelHandle;
36 using android::pdx::ServiceBase;
37 using android::pdx::ServiceDispatcher;
38 using android::pdx::Status;
39 using android::pdx::Transaction;
40 using android::pdx::uds::Endpoint;
41
42 namespace {
43
44 const size_t kLargeDataSize = 100000;
45
46 const char kTestServicePath[] = "socket_test";
47 const char kTestService1[] = "1";
48 const char kTestService2[] = "2";
49
50 enum test_op_codes {
51 TEST_OP_GET_SERVICE_ID,
52 TEST_OP_SET_TEST_CHANNEL,
53 TEST_OP_GET_THIS_CHANNEL_ID,
54 TEST_OP_GET_TEST_CHANNEL_ID,
55 TEST_OP_CHECK_CHANNEL_ID,
56 TEST_OP_CHECK_CHANNEL_OBJECT,
57 TEST_OP_CHECK_CHANNEL_FROM_OTHER_SERVICE,
58 TEST_OP_GET_NEW_CHANNEL,
59 TEST_OP_GET_NEW_CHANNEL_FROM_OTHER_SERVICE,
60 TEST_OP_GET_THIS_PROCESS_ID,
61 TEST_OP_GET_THIS_THREAD_ID,
62 TEST_OP_GET_THIS_EUID,
63 TEST_OP_GET_THIS_EGID,
64 TEST_OP_IMPULSE,
65 TEST_OP_POLLHUP_FROM_SERVICE,
66 TEST_OP_POLLIN_FROM_SERVICE,
67 TEST_OP_SEND_LARGE_DATA_RETURN_SUM,
68 };
69
70 using ImpulsePayload = std::array<std::uint8_t, sizeof(MessageInfo::impulse)>;
71
72 // The test service creates a TestChannel for every client (channel) that
73 // connects. This represents the service-side context for each client.
74 class TestChannel : public Channel {
75 public:
TestChannel(int channel_id)76 explicit TestChannel(int channel_id) : channel_id_(channel_id) {}
77
channel_id() const78 int channel_id() const { return channel_id_; }
79
80 private:
81 friend class TestService;
82
83 int channel_id_;
84
85 TestChannel(const TestChannel&) = delete;
86 void operator=(const TestChannel&) = delete;
87 };
88
89 // Test service that creates a TestChannel for each channel and responds to test
90 // messages.
91 class TestService : public ServiceBase<TestService> {
92 public:
OnChannelOpen(Message & message)93 std::shared_ptr<Channel> OnChannelOpen(Message& message) override {
94 return std::make_shared<TestChannel>(message.GetChannelId());
95 }
96
OnChannelClose(Message &,const std::shared_ptr<Channel> & channel)97 void OnChannelClose(Message& /*message*/,
98 const std::shared_ptr<Channel>& channel) override {
99 if (test_channel_ == channel)
100 test_channel_ = nullptr;
101 }
102
HandleImpulse(Message & message)103 void HandleImpulse(Message& message) override {
104 switch (message.GetOp()) {
105 case TEST_OP_SET_TEST_CHANNEL:
106 test_channel_ = message.GetChannel<TestChannel>();
107 break;
108
109 case TEST_OP_IMPULSE: {
110 impulse_payload_.fill(0);
111 std::copy(message.ImpulseBegin(), message.ImpulseEnd(),
112 impulse_payload_.begin());
113 break;
114 }
115
116 case TEST_OP_POLLHUP_FROM_SERVICE: {
117 message.ModifyChannelEvents(0, EPOLLHUP);
118 break;
119 }
120 }
121 }
122
HandleMessage(Message & message)123 Status<void> HandleMessage(Message& message) override {
124 switch (message.GetOp()) {
125 case TEST_OP_GET_SERVICE_ID:
126 REPLY_MESSAGE_RETURN(message, service_id_, {});
127
128 // Set the test channel to the TestChannel for the current channel. Other
129 // messages can use this to perform tests.
130 case TEST_OP_SET_TEST_CHANNEL:
131 test_channel_ = message.GetChannel<TestChannel>();
132 REPLY_MESSAGE_RETURN(message, 0, {});
133
134 // Return the channel id for the current channel.
135 case TEST_OP_GET_THIS_CHANNEL_ID:
136 REPLY_MESSAGE_RETURN(message, message.GetChannelId(), {});
137
138 // Return the channel id for the test channel.
139 case TEST_OP_GET_TEST_CHANNEL_ID:
140 if (test_channel_)
141 REPLY_MESSAGE_RETURN(message, test_channel_->channel_id(), {});
142 else
143 REPLY_ERROR_RETURN(message, ENOENT, {});
144
145 // Test check channel feature.
146 case TEST_OP_CHECK_CHANNEL_ID: {
147 ChannelReference ref = 0;
148 if (!message.ReadAll(&ref, sizeof(ref)))
149 REPLY_ERROR_RETURN(message, EIO, {});
150
151 const Status<int> ret = message.CheckChannel<TestChannel>(ref, nullptr);
152 REPLY_MESSAGE_RETURN(message, ret, {});
153 }
154
155 case TEST_OP_CHECK_CHANNEL_OBJECT: {
156 std::shared_ptr<TestChannel> channel;
157 ChannelReference ref = 0;
158 if (!message.ReadAll(&ref, sizeof(ref)))
159 REPLY_ERROR_RETURN(message, EIO, {});
160
161 const Status<int> ret =
162 message.CheckChannel<TestChannel>(ref, &channel);
163 if (!ret)
164 REPLY_MESSAGE_RETURN(message, ret, {});
165
166 if (channel != nullptr)
167 REPLY_MESSAGE_RETURN(message, channel->channel_id(), {});
168 else
169 REPLY_ERROR_RETURN(message, ENODATA, {});
170 }
171
172 case TEST_OP_CHECK_CHANNEL_FROM_OTHER_SERVICE: {
173 ChannelReference ref = 0;
174 if (!message.ReadAll(&ref, sizeof(ref)))
175 REPLY_ERROR_RETURN(message, EIO, {});
176
177 const Status<int> ret = message.CheckChannel<TestChannel>(
178 other_service_.get(), ref, nullptr);
179 REPLY_MESSAGE_RETURN(message, ret, {});
180 }
181
182 case TEST_OP_GET_NEW_CHANNEL: {
183 auto channel = std::make_shared<TestChannel>(-1);
184 Status<RemoteChannelHandle> channel_handle =
185 message.PushChannel(0, channel, &channel->channel_id_);
186 REPLY_MESSAGE_RETURN(message, channel_handle, {});
187 }
188
189 case TEST_OP_GET_NEW_CHANNEL_FROM_OTHER_SERVICE: {
190 if (!other_service_)
191 REPLY_ERROR_RETURN(message, EINVAL, {});
192
193 auto channel = std::make_shared<TestChannel>(-1);
194 Status<RemoteChannelHandle> channel_handle = message.PushChannel(
195 other_service_.get(), 0, channel, &channel->channel_id_);
196 REPLY_MESSAGE_RETURN(message, channel_handle, {});
197 }
198
199 case TEST_OP_GET_THIS_PROCESS_ID:
200 REPLY_MESSAGE_RETURN(message, message.GetProcessId(), {});
201
202 case TEST_OP_GET_THIS_THREAD_ID:
203 REPLY_MESSAGE_RETURN(message, message.GetThreadId(), {});
204
205 case TEST_OP_GET_THIS_EUID:
206 REPLY_MESSAGE_RETURN(message, message.GetEffectiveUserId(), {});
207
208 case TEST_OP_GET_THIS_EGID:
209 REPLY_MESSAGE_RETURN(message, message.GetEffectiveGroupId(), {});
210
211 case TEST_OP_POLLIN_FROM_SERVICE:
212 REPLY_MESSAGE_RETURN(message, message.ModifyChannelEvents(0, EPOLLIN),
213 {});
214
215 case TEST_OP_SEND_LARGE_DATA_RETURN_SUM: {
216 std::array<int, kLargeDataSize> data_array;
217 size_t size_to_read = data_array.size() * sizeof(int);
218 if (!message.ReadAll(data_array.data(), size_to_read)) {
219 REPLY_ERROR_RETURN(message, EIO, {});
220 }
221 int sum = std::accumulate(data_array.begin(), data_array.end(), 0);
222 REPLY_MESSAGE_RETURN(message, sum, {});
223 }
224
225 default:
226 return Service::DefaultHandleMessage(message);
227 }
228 }
229
GetImpulsePayload() const230 const ImpulsePayload& GetImpulsePayload() const { return impulse_payload_; }
231
232 private:
233 friend BASE;
234
235 std::shared_ptr<TestChannel> test_channel_;
236 std::shared_ptr<TestService> other_service_;
237 int service_id_;
238 ImpulsePayload impulse_payload_;
239
240 static std::atomic<int> service_counter_;
241
TestService(const std::string & name,const std::shared_ptr<TestService> & other_service)242 TestService(const std::string& name,
243 const std::shared_ptr<TestService>& other_service)
244 : TestService(name, other_service, false) {}
245
TestService(const std::string & name,const std::shared_ptr<TestService> & other_service,bool blocking)246 TestService(const std::string& name,
247 const std::shared_ptr<TestService>& other_service, bool blocking)
248 : BASE(std::string("TestService") + name,
249 Endpoint::CreateAndBindSocket(kTestServicePath + name, blocking)),
250 other_service_(other_service),
251 service_id_(service_counter_++) {}
252
TestService(const std::string & name)253 explicit TestService(const std::string& name) : TestService(name, nullptr) {}
254
255 TestService(const TestService&) = delete;
256 void operator=(const TestService&) = delete;
257 };
258
259 std::atomic<int> TestService::service_counter_;
260
261 // Test client to send messages to the test service.
262 class TestClient : public ClientBase<TestClient> {
263 public:
264 // Requests the service id of the service this channel is connected to.
GetServiceId()265 int GetServiceId() {
266 Transaction trans{*this};
267 return ReturnStatusOrError(trans.Send<int>(TEST_OP_GET_SERVICE_ID));
268 }
269
270 // Requests the test channel to be set to this client's channel.
SetTestChannel()271 int SetTestChannel() {
272 Transaction trans{*this};
273 return ReturnStatusOrError(trans.Send<int>(TEST_OP_SET_TEST_CHANNEL));
274 }
275
276 // Request the test channel to be set to this client's channel using an async
277 // message.
SetTestChannelAsync()278 int SetTestChannelAsync() {
279 return ReturnStatusOrError(SendImpulse(TEST_OP_SET_TEST_CHANNEL));
280 }
281
282 // Sends a test async message with payload.
SendAsync(const void * buffer,size_t length)283 int SendAsync(const void* buffer, size_t length) {
284 Transaction trans{*this};
285 return ReturnStatusOrError(SendImpulse(TEST_OP_IMPULSE, buffer, length));
286 }
287
288 // Requests the channel id for this client.
GetThisChannelId()289 int GetThisChannelId() {
290 Transaction trans{*this};
291 return ReturnStatusOrError(trans.Send<int>(TEST_OP_GET_THIS_CHANNEL_ID));
292 }
293
294 // Requests the channel id of the test channel.
GetTestChannelId()295 int GetTestChannelId() {
296 Transaction trans{*this};
297 return ReturnStatusOrError(trans.Send<int>(TEST_OP_GET_TEST_CHANNEL_ID));
298 }
299
300 // Checks whether the fd |channel_id| is a channel to the test service.
301 // Returns the channel id of the channel.
CheckChannelIdArgument(BorrowedChannelHandle channel)302 int CheckChannelIdArgument(BorrowedChannelHandle channel) {
303 Transaction trans{*this};
304 ChannelReference ref = trans.PushChannelHandle(channel).get();
305 return ReturnStatusOrError(trans.Send<int>(TEST_OP_CHECK_CHANNEL_ID, &ref,
306 sizeof(ref), nullptr, 0));
307 }
308
309 // Checks whether the fd |channel_id| is a channel to the test service.
310 // Returns the channel id of the channel exercising the context pointer.
CheckChannelObjectArgument(BorrowedChannelHandle channel)311 int CheckChannelObjectArgument(BorrowedChannelHandle channel) {
312 Transaction trans{*this};
313 ChannelReference ref = trans.PushChannelHandle(channel).get();
314 return ReturnStatusOrError(trans.Send<int>(TEST_OP_CHECK_CHANNEL_OBJECT,
315 &ref, sizeof(ref), nullptr, 0));
316 }
317
318 // Checks whether the fd |channel_fd| is a channel to the other test service.
319 // Returns 0 on success.
CheckChannelFromOtherService(BorrowedChannelHandle channel)320 int CheckChannelFromOtherService(BorrowedChannelHandle channel) {
321 Transaction trans{*this};
322 ChannelReference ref = trans.PushChannelHandle(channel).get();
323 return ReturnStatusOrError(
324 trans.Send<int>(TEST_OP_CHECK_CHANNEL_FROM_OTHER_SERVICE, &ref,
325 sizeof(ref), nullptr, 0));
326 }
327
328 // Requests a new channel to the service.
GetNewChannel()329 std::unique_ptr<TestClient> GetNewChannel() {
330 Transaction trans{*this};
331 auto status = trans.Send<LocalChannelHandle>(TEST_OP_GET_NEW_CHANNEL);
332 if (status)
333 return TestClient::Create(status.take());
334 else
335 return nullptr;
336 }
337
338 // Requests a new channel to the other service.
GetNewChannelFromOtherService()339 std::unique_ptr<TestClient> GetNewChannelFromOtherService() {
340 Transaction trans{*this};
341 auto status = trans.Send<LocalChannelHandle>(
342 TEST_OP_GET_NEW_CHANNEL_FROM_OTHER_SERVICE);
343 if (status)
344 return TestClient::Create(status.take());
345 else
346 return nullptr;
347 }
348
349 // Requests an id from the message description.
GetThisProcessId()350 pid_t GetThisProcessId() {
351 Transaction trans{*this};
352 return ReturnStatusOrError(trans.Send<int>(TEST_OP_GET_THIS_PROCESS_ID));
353 }
GetThisThreadId()354 pid_t GetThisThreadId() {
355 Transaction trans{*this};
356 return ReturnStatusOrError(trans.Send<int>(TEST_OP_GET_THIS_THREAD_ID));
357 }
GetThisEffectiveUserId()358 uid_t GetThisEffectiveUserId() {
359 Transaction trans{*this};
360 return ReturnStatusOrError(trans.Send<int>(TEST_OP_GET_THIS_EUID));
361 }
GetThisEffectiveGroupId()362 gid_t GetThisEffectiveGroupId() {
363 Transaction trans{*this};
364 return ReturnStatusOrError(trans.Send<int>(TEST_OP_GET_THIS_EGID));
365 }
366
SendPollHupEvent()367 int SendPollHupEvent() {
368 return ReturnStatusOrError(SendImpulse(TEST_OP_POLLHUP_FROM_SERVICE));
369 }
370
SendPollInEvent()371 int SendPollInEvent() {
372 Transaction trans{*this};
373 return ReturnStatusOrError(trans.Send<int>(TEST_OP_POLLIN_FROM_SERVICE));
374 }
375
SendLargeDataReturnSum(const std::array<int,kLargeDataSize> & data_array)376 int SendLargeDataReturnSum(
377 const std::array<int, kLargeDataSize>& data_array) {
378 Transaction trans{*this};
379 return ReturnStatusOrError(
380 trans.Send<int>(TEST_OP_SEND_LARGE_DATA_RETURN_SUM, data_array.data(),
381 data_array.size() * sizeof(int), nullptr, 0));
382 }
383
GetEventMask(int events)384 Status<int> GetEventMask(int events) {
385 if (auto* client_channel = GetChannel()) {
386 return client_channel->GetEventMask(events);
387 } else {
388 return ErrorStatus(EINVAL);
389 }
390 }
391
392 using ClientBase<TestClient>::event_fd;
393
394 enum : size_t { kMaxPayload = MAX_IMPULSE_LENGTH };
395
396 private:
397 friend BASE;
398
TestClient(const std::string & name)399 explicit TestClient(const std::string& name)
400 : BASE{android::pdx::uds::ClientChannelFactory::Create(kTestServicePath +
401 name)} {}
402
TestClient(LocalChannelHandle channel)403 explicit TestClient(LocalChannelHandle channel)
404 : BASE{android::pdx::uds::ClientChannel::Create(std::move(channel))} {}
405
406 TestClient(const TestClient&) = delete;
407 void operator=(const TestClient&) = delete;
408 };
409
410 } // anonymous namespace
411
412 // Use a test fixture to ensure proper order of cleanup between clients,
413 // services, and the dispatcher. These objects are cleaned up in the same
414 // thread, order is important; either the service or the client must be
415 // destroyed before the dispatcher is stopped. The reason for this is that
416 // clients send blocking "close" messages to their respective services on
417 // destruction. If this happens after the dispatcher is stopped the client
418 // destructor will get blocked waiting for a reply that will never come. In
419 // normal use of the service framework this is never an issue because clients
420 // and the dispatcher for the same service are never destructed in the same
421 // thread (they live in different processes).
422 class ServiceFrameworkTest : public ::testing::Test {
423 protected:
424 std::unique_ptr<ServiceDispatcher> dispatcher_;
425 std::thread dispatch_thread_;
426
SetUp()427 void SetUp() override {
428 // Create a dispatcher to handle messages to services.
429 dispatcher_ = android::pdx::ServiceDispatcher::Create();
430 ASSERT_NE(nullptr, dispatcher_);
431
432 // Start the message dispatch loop in a separate thread.
433 dispatch_thread_ = std::thread(
434 std::bind(&ServiceDispatcher::EnterDispatchLoop, dispatcher_.get()));
435 }
436
TearDown()437 void TearDown() override {
438 if (dispatcher_) {
439 // Cancel the dispatcher and wait for the thread to terminate. Explicitly
440 // join the thread so that destruction doesn't deallocate the dispatcher
441 // before the thread finishes.
442 dispatcher_->SetCanceled(true);
443 dispatch_thread_.join();
444 }
445 }
446 };
447
448 // Test basic operation of TestService/TestClient classes.
TEST_F(ServiceFrameworkTest,BasicClientService)449 TEST_F(ServiceFrameworkTest, BasicClientService) {
450 // Create a test service and add it to the dispatcher.
451 auto service = TestService::Create(kTestService1);
452 ASSERT_NE(nullptr, service);
453 ASSERT_EQ(0, dispatcher_->AddService(service));
454
455 // Create a client to service.
456 auto client = TestClient::Create(kTestService1);
457 ASSERT_NE(nullptr, client);
458
459 // Get the channel id that will be returned by the next tests.
460 const int channel_id = client->GetThisChannelId();
461 EXPECT_LE(0, channel_id);
462
463 // Check return value before test channel is set.
464 EXPECT_EQ(-ENOENT, client->GetTestChannelId());
465
466 // Set test channel and perform the test again.
467 EXPECT_EQ(0, client->SetTestChannel());
468 EXPECT_EQ(channel_id, client->GetTestChannelId());
469 }
470
471 // Test impulses.
TEST_F(ServiceFrameworkTest,Impulse)472 TEST_F(ServiceFrameworkTest, Impulse) {
473 // Create a test service and add it to the dispatcher.
474 auto service = TestService::Create(kTestService1);
475 ASSERT_NE(nullptr, service);
476 ASSERT_EQ(0, dispatcher_->AddService(service));
477
478 auto client = TestClient::Create(kTestService1);
479 ASSERT_NE(nullptr, client);
480
481 // Get the channel id that will be returned by the next tests.
482 const int channel_id = client->GetThisChannelId();
483 EXPECT_LE(0, channel_id);
484
485 // Check return value before test channel is set.
486 EXPECT_EQ(-ENOENT, client->GetTestChannelId());
487
488 // Set test channel with an impulse and perform the test again.
489 EXPECT_EQ(0, client->SetTestChannelAsync());
490 EXPECT_EQ(channel_id, client->GetTestChannelId());
491
492 ImpulsePayload expected_payload = {{'a', 'b', 'c'}};
493 EXPECT_EQ(0, client->SendAsync(expected_payload.data(), 3));
494 // Send a synchronous message to make sure the async message is handled before
495 // we check the payload.
496 client->GetThisChannelId();
497 EXPECT_EQ(expected_payload, service->GetImpulsePayload());
498
499 // Impulse payloads are limited to 4 machine words.
500 EXPECT_EQ(
501 0, client->SendAsync(expected_payload.data(), TestClient::kMaxPayload));
502 EXPECT_EQ(-EINVAL, client->SendAsync(expected_payload.data(),
503 TestClient::kMaxPayload + 1));
504
505 // Test invalid pointer.
506 const std::uint8_t* invalid_pointer = nullptr;
507 EXPECT_EQ(-EINVAL, client->SendAsync(invalid_pointer, sizeof(int)));
508 }
509
510 // Test impulses.
TEST_F(ServiceFrameworkTest,ImpulseHangup)511 TEST_F(ServiceFrameworkTest, ImpulseHangup) {
512 // Create a test service and add it to the dispatcher.
513 auto service = TestService::Create(kTestService1);
514 ASSERT_NE(nullptr, service);
515 ASSERT_EQ(0, dispatcher_->AddService(service));
516
517 auto client = TestClient::Create(kTestService1);
518 ASSERT_NE(nullptr, client);
519
520 const int kMaxIterations = 1000;
521 for (int i = 0; i < kMaxIterations; i++) {
522 auto impulse_client = TestClient::Create(kTestService1);
523 ASSERT_NE(nullptr, impulse_client);
524
525 const uint8_t a = (i >> 0) & 0xff;
526 const uint8_t b = (i >> 8) & 0xff;
527 const uint8_t c = (i >> 16) & 0xff;
528 const uint8_t d = (i >> 24) & 0xff;
529 ImpulsePayload expected_payload = {{a, b, c, d}};
530 EXPECT_EQ(0, impulse_client->SendAsync(expected_payload.data(), 4));
531
532 // Hangup the impulse test client, then send a sync message over client to
533 // make sure the hangup message is handled before checking the impulse
534 // payload.
535 impulse_client = nullptr;
536 client->GetThisChannelId();
537 EXPECT_EQ(expected_payload, service->GetImpulsePayload());
538 }
539 }
540
541 // Test Message::PushChannel/Service::PushChannel API.
TEST_F(ServiceFrameworkTest,PushChannel)542 TEST_F(ServiceFrameworkTest, PushChannel) {
543 // Create a test service and add it to the dispatcher.
544 auto other_service = TestService::Create(kTestService1);
545 ASSERT_NE(nullptr, other_service);
546 ASSERT_EQ(0, dispatcher_->AddService(other_service));
547
548 // Create a second test service and add it to the dispatcher.
549 auto service = TestService::Create(kTestService2, other_service);
550 ASSERT_NE(nullptr, service);
551 ASSERT_EQ(0, dispatcher_->AddService(service));
552
553 // Create a client to the second test service.
554 auto client1 = TestClient::Create(kTestService2);
555 ASSERT_NE(nullptr, client1);
556
557 // Test the creation of new channels using the push APIs.
558 const int channel_id1 = client1->GetThisChannelId();
559 EXPECT_LE(0, channel_id1);
560
561 auto client2 = client1->GetNewChannel();
562 EXPECT_NE(nullptr, client2);
563 EXPECT_NE(client1->event_fd(), client2->event_fd());
564
565 const int channel_id2 = client2->GetThisChannelId();
566 EXPECT_LE(0, channel_id2);
567 EXPECT_NE(channel_id1, channel_id2);
568
569 auto client3 = client1->GetNewChannelFromOtherService();
570 EXPECT_NE(nullptr, client3);
571 EXPECT_NE(client1->event_fd(), client3->event_fd());
572
573 const int channel_id3 = client3->GetThisChannelId();
574 EXPECT_LE(0, channel_id3);
575
576 // Test which services the channels are connected to.
577 const int service_id1 = client1->GetServiceId();
578 EXPECT_LE(0, service_id1);
579
580 const int service_id2 = client2->GetServiceId();
581 EXPECT_LE(0, service_id2);
582
583 const int service_id3 = client3->GetServiceId();
584 EXPECT_LE(0, service_id3);
585
586 EXPECT_EQ(service_id1, service_id2);
587 EXPECT_NE(service_id1, service_id3);
588 }
589
590 // Tests process id, thread id, effective user id, and effective group id
591 // returned in the message description.
TEST_F(ServiceFrameworkTest,Ids)592 TEST_F(ServiceFrameworkTest, Ids) {
593 // Create a test service and add it to the dispatcher.
594 auto service = TestService::Create(kTestService1);
595 ASSERT_NE(nullptr, service);
596 ASSERT_EQ(0, dispatcher_->AddService(service));
597
598 // Create a client to service.
599 auto client = TestClient::Create(kTestService1);
600 ASSERT_NE(nullptr, client);
601
602 // Pids 0-2 are defined, no user task should have them.
603
604 const pid_t process_id1 = client->GetThisProcessId();
605 EXPECT_LT(2, process_id1);
606
607 pid_t process_id2;
608
609 std::thread thread([&]() { process_id2 = client->GetThisProcessId(); });
610 thread.join();
611
612 EXPECT_LT(2, process_id2);
613 EXPECT_EQ(process_id1, process_id2);
614
615 // This test must run as root for the rest of these tests to work.
616 const int euid1 = client->GetThisEffectiveUserId();
617 ASSERT_EQ(0, euid1);
618
619 const int egid1 = client->GetThisEffectiveGroupId();
620 EXPECT_EQ(0, egid1);
621
622 // Set effective uid/gid to system.
623 ASSERT_EQ(0, setegid(AID_SYSTEM));
624 ASSERT_EQ(0, seteuid(AID_SYSTEM));
625
626 const int euid2 = client->GetThisEffectiveUserId();
627 EXPECT_EQ(AID_SYSTEM, euid2);
628
629 const int egid2 = client->GetThisEffectiveGroupId();
630 EXPECT_EQ(AID_SYSTEM, egid2);
631
632 // Set the euid/egid back to root.
633 ASSERT_EQ(0, setegid(0));
634 ASSERT_EQ(0, seteuid(0));
635 }
636
TEST_F(ServiceFrameworkTest,PollIn)637 TEST_F(ServiceFrameworkTest, PollIn) {
638 // Create a test service and add it to the dispatcher.
639 auto service = TestService::Create(kTestService1);
640 ASSERT_NE(nullptr, service);
641 ASSERT_EQ(0, dispatcher_->AddService(service));
642
643 // Create a client to service.
644 auto client = TestClient::Create(kTestService1);
645 ASSERT_NE(nullptr, client);
646
647 pollfd pfd{client->event_fd(), POLLIN, 0};
648 int count = poll(&pfd, 1, 0);
649 ASSERT_EQ(0, count);
650
651 client->SendPollInEvent();
652
653 count = poll(&pfd, 1, 10000 /*10s*/);
654 ASSERT_EQ(1, count);
655 ASSERT_TRUE((POLLIN & pfd.revents) != 0);
656 }
657
TEST_F(ServiceFrameworkTest,PollHup)658 TEST_F(ServiceFrameworkTest, PollHup) {
659 // Create a test service and add it to the dispatcher.
660 auto service = TestService::Create(kTestService1);
661 ASSERT_NE(nullptr, service);
662 ASSERT_EQ(0, dispatcher_->AddService(service));
663
664 // Create a client to service.
665 auto client = TestClient::Create(kTestService1);
666 ASSERT_NE(nullptr, client);
667
668 pollfd pfd{client->event_fd(), POLLIN, 0};
669 int count = poll(&pfd, 1, 0);
670 ASSERT_EQ(0, count);
671
672 client->SendPollHupEvent();
673
674 count = poll(&pfd, 1, 10000 /*10s*/);
675 ASSERT_EQ(1, count);
676 auto event_status = client->GetEventMask(pfd.revents);
677 ASSERT_TRUE(event_status.ok());
678 ASSERT_TRUE((EPOLLHUP & event_status.get()) != 0);
679 }
680
TEST_F(ServiceFrameworkTest,LargeDataSum)681 TEST_F(ServiceFrameworkTest, LargeDataSum) {
682 // Create a test service and add it to the dispatcher.
683 auto service = TestService::Create(kTestService1);
684 ASSERT_NE(nullptr, service);
685 ASSERT_EQ(0, dispatcher_->AddService(service));
686
687 // Create a client to service.
688 auto client = TestClient::Create(kTestService1);
689 ASSERT_NE(nullptr, client);
690
691 std::array<int, kLargeDataSize> data_array;
692 std::iota(data_array.begin(), data_array.end(), 0);
693 int expected_sum = std::accumulate(data_array.begin(), data_array.end(), 0);
694 int sum = client->SendLargeDataReturnSum(data_array);
695 ASSERT_EQ(expected_sum, sum);
696 }
697
TEST_F(ServiceFrameworkTest,Cancel)698 TEST_F(ServiceFrameworkTest, Cancel) {
699 // Create a test service and add it to the dispatcher.
700 auto service = TestService::Create(kTestService1, nullptr, true);
701 ASSERT_NE(nullptr, service);
702 ASSERT_EQ(0, dispatcher_->AddService(service));
703
704 // Create a client to service.
705 auto client = TestClient::Create(kTestService1);
706 ASSERT_NE(nullptr, client);
707
708 auto previous_time = std::chrono::system_clock::now();
709 dispatcher_->ReceiveAndDispatch(100); // 0.1 seconds should block.
710 auto time = std::chrono::system_clock::now();
711 ASSERT_LE(100, std::chrono::duration_cast<std::chrono::milliseconds>(
712 time - previous_time)
713 .count());
714 service->Cancel();
715 // Non-blocking. Return immediately.
716 dispatcher_->ReceiveAndDispatch(-1);
717 dispatcher_->ReceiveAndDispatch(-1);
718 }
719