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