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
26using android::pdx::BorrowedChannelHandle;
27using android::pdx::Channel;
28using android::pdx::ChannelReference;
29using android::pdx::ClientBase;
30using android::pdx::ErrorStatus;
31using android::pdx::LocalChannelHandle;
32using android::pdx::LocalHandle;
33using android::pdx::Message;
34using android::pdx::MessageInfo;
35using android::pdx::RemoteChannelHandle;
36using android::pdx::ServiceBase;
37using android::pdx::ServiceDispatcher;
38using android::pdx::Status;
39using android::pdx::Transaction;
40using android::pdx::uds::Endpoint;
41
42namespace {
43
44const size_t kLargeDataSize = 100000;
45
46const char kTestServicePath[] = "socket_test";
47const char kTestService1[] = "1";
48const char kTestService2[] = "2";
49
50enum 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
70using 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.
74class TestChannel : public Channel {
75 public:
76  explicit TestChannel(int channel_id) : channel_id_(channel_id) {}
77
78  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.
91class TestService : public ServiceBase<TestService> {
92 public:
93  std::shared_ptr<Channel> OnChannelOpen(Message& message) override {
94    return std::make_shared<TestChannel>(message.GetChannelId());
95  }
96
97  void OnChannelClose(Message& /*message*/,
98                      const std::shared_ptr<Channel>& channel) override {
99    if (test_channel_ == channel)
100      test_channel_ = nullptr;
101  }
102
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
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
230  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
242  TestService(const std::string& name,
243              const std::shared_ptr<TestService>& other_service)
244      : TestService(name, other_service, false) {}
245
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
253  explicit TestService(const std::string& name) : TestService(name, nullptr) {}
254
255  TestService(const TestService&) = delete;
256  void operator=(const TestService&) = delete;
257};
258
259std::atomic<int> TestService::service_counter_;
260
261// Test client to send messages to the test service.
262class TestClient : public ClientBase<TestClient> {
263 public:
264  // Requests the service id of the service this channel is connected to.
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.
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.
278  int SetTestChannelAsync() {
279    return ReturnStatusOrError(SendImpulse(TEST_OP_SET_TEST_CHANNEL));
280  }
281
282  // Sends a test async message with payload.
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.
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.
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.
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.
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.
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.
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.
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.
350  pid_t GetThisProcessId() {
351    Transaction trans{*this};
352    return ReturnStatusOrError(trans.Send<int>(TEST_OP_GET_THIS_PROCESS_ID));
353  }
354  pid_t GetThisThreadId() {
355    Transaction trans{*this};
356    return ReturnStatusOrError(trans.Send<int>(TEST_OP_GET_THIS_THREAD_ID));
357  }
358  uid_t GetThisEffectiveUserId() {
359    Transaction trans{*this};
360    return ReturnStatusOrError(trans.Send<int>(TEST_OP_GET_THIS_EUID));
361  }
362  gid_t GetThisEffectiveGroupId() {
363    Transaction trans{*this};
364    return ReturnStatusOrError(trans.Send<int>(TEST_OP_GET_THIS_EGID));
365  }
366
367  int SendPollHupEvent() {
368    return ReturnStatusOrError(SendImpulse(TEST_OP_POLLHUP_FROM_SERVICE));
369  }
370
371  int SendPollInEvent() {
372    Transaction trans{*this};
373    return ReturnStatusOrError(trans.Send<int>(TEST_OP_POLLIN_FROM_SERVICE));
374  }
375
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
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
399  explicit TestClient(const std::string& name)
400      : BASE{android::pdx::uds::ClientChannelFactory::Create(kTestServicePath +
401                                                             name)} {}
402
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).
422class ServiceFrameworkTest : public ::testing::Test {
423 protected:
424  std::unique_ptr<ServiceDispatcher> dispatcher_;
425  std::thread dispatch_thread_;
426
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
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.
449TEST_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.
472TEST_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.
511TEST_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.
542TEST_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.
592TEST_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
637TEST_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
658TEST_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
681TEST_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
698TEST_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