remote_method_tests.cpp revision 5a244ed36c8e45fd95b89ff916caf083fb182ec1
1#include <errno.h> 2#include <fcntl.h> 3#include <unistd.h> 4 5#include <array> 6#include <cstdint> 7#include <memory> 8#include <numeric> 9#include <string> 10#include <thread> 11 12#include <gtest/gtest.h> 13#include <pdx/channel_handle.h> 14#include <pdx/client.h> 15#include <pdx/rpc/remote_method.h> 16#include <pdx/rpc/serializable.h> 17#include <pdx/service.h> 18#include <pdx/service_dispatcher.h> 19#include <uds/client_channel.h> 20#include <uds/client_channel_factory.h> 21#include <uds/service_endpoint.h> 22 23using android::pdx::BorrowedHandle; 24using android::pdx::Channel; 25using android::pdx::ClientBase; 26using android::pdx::ErrorStatus; 27using android::pdx::LocalChannelHandle; 28using android::pdx::LocalHandle; 29using android::pdx::Message; 30using android::pdx::RemoteChannelHandle; 31using android::pdx::RemoteHandle; 32using android::pdx::ServiceBase; 33using android::pdx::ServiceDispatcher; 34using android::pdx::Status; 35using android::pdx::uds::Endpoint; 36using namespace android::pdx::rpc; 37 38namespace { 39 40std::string Rot13(const std::string& s) { 41 std::string text = s; 42 std::transform(std::begin(text), std::end(text), std::begin(text), 43 [](char c) -> char { 44 if (!std::isalpha(c)) { 45 return c; 46 } else { 47 const char pivot = std::isupper(c) ? 'A' : 'a'; 48 return (c - pivot + 13) % 26 + pivot; 49 } 50 }); 51 return text; 52} 53 54// Defines a serializable user type that may be transferred between client and 55// service. 56struct TestType { 57 int a; 58 float b; 59 std::string c; 60 61 TestType() {} 62 TestType(int a, float b, const std::string& c) : a(a), b(b), c(c) {} 63 64 // Make gtest expressions simpler by defining equality operator. This is not 65 // needed for serialization. 66 bool operator==(const TestType& other) const { 67 return a == other.a && b == other.b && c == other.c; 68 } 69 70 private: 71 PDX_SERIALIZABLE_MEMBERS(TestType, a, b, c); 72}; 73 74struct DerivedTestType : public TestType { 75 DerivedTestType() : TestType() {} 76 DerivedTestType(int a, float b) : TestType(a, b, "constant") {} 77}; 78 79// Defines a serializable user type with a LocalHandle member. 80struct TestFdType { 81 int a; 82 LocalHandle fd; 83 84 TestFdType() {} 85 TestFdType(int a, LocalHandle fd) : a(a), fd(std::move(fd)) {} 86 87 private: 88 PDX_SERIALIZABLE_MEMBERS(TestFdType, a, fd); 89}; 90 91// Defines a serializable user template type with a FileHandle member. 92template <typename FileHandleType> 93struct TestTemplateType { 94 FileHandleType fd; 95 96 TestTemplateType() {} 97 TestTemplateType(FileHandleType fd) : fd(std::move(fd)) {} 98 99 private: 100 PDX_SERIALIZABLE_MEMBERS(TestTemplateType<FileHandleType>, fd); 101}; 102 103struct BasicStruct { 104 int a; 105 int b; 106 std::string c; 107 108 private: 109 PDX_SERIALIZABLE_MEMBERS(BasicStruct, a, b, c); 110}; 111 112using BasicStructTraits = SerializableTraits<BasicStruct>; 113 114struct NonSerializableType { 115 int a; 116 int b; 117 std::string c; 118}; 119 120struct IncorrectlyDefinedSerializableType { 121 int a; 122 int b; 123 124 private: 125 using SerializableMembers = std::tuple<int, int>; 126}; 127 128// Defines the contract between the client and service, including ServiceFS 129// endpoint path, method opcodes, and remote method signatures. 130struct TestInterface final { 131 // Service path. 132 static constexpr char kClientPath[] = "socket_test"; 133 134 // Op codes. 135 enum { 136 kOpAdd = 0, 137 kOpFoo, 138 kOpConcatenate, 139 kOpWriteBuffer, 140 kOpStringLength, 141 kOpSendTestType, 142 kOpSendBasicStruct, 143 kOpSendVector, 144 kOpRot13, 145 kOpNoArgs, 146 kOpSendFile, 147 kOpGetFile, 148 kOpGetTestFdType, 149 kOpOpenFiles, 150 kOpReadFile, 151 kOpPushChannel, 152 kOpPositive, 153 }; 154 155 // Methods. 156 PDX_REMOTE_METHOD(Add, kOpAdd, int(int, int)); 157 PDX_REMOTE_METHOD(Foo, kOpFoo, int(int, const std::string&)); 158 PDX_REMOTE_METHOD(Concatenate, kOpConcatenate, 159 std::string(const std::string&, const std::string&)); 160 PDX_REMOTE_METHOD(SumVector, kOpWriteBuffer, int(const std::vector<int>&)); 161 PDX_REMOTE_METHOD(StringLength, kOpStringLength, int(const std::string&)); 162 PDX_REMOTE_METHOD(SendTestType, kOpSendTestType, TestType(const TestType&)); 163 PDX_REMOTE_METHOD(SendBasicStruct, kOpSendBasicStruct, 164 BasicStruct(const BasicStruct&)); 165 PDX_REMOTE_METHOD(SendVector, kOpSendVector, 166 std::string(const std::vector<TestType>&)); 167 PDX_REMOTE_METHOD(Rot13, kOpRot13, std::string(const std::string&)); 168 PDX_REMOTE_METHOD(NoArgs, kOpNoArgs, int(Void)); 169 PDX_REMOTE_METHOD(SendFile, kOpSendFile, int(const LocalHandle& fd)); 170 PDX_REMOTE_METHOD(GetFile, kOpGetFile, LocalHandle(const std::string&, int)); 171 PDX_REMOTE_METHOD(GetTestFdType, kOpGetTestFdType, 172 TestFdType(int, const std::string&, int)); 173 PDX_REMOTE_METHOD(OpenFiles, kOpOpenFiles, 174 std::vector<LocalHandle>( 175 const std::vector<std::pair<std::string, int>>&)); 176 PDX_REMOTE_METHOD(ReadFile, kOpReadFile, 177 std::pair<int, BufferWrapper<std::uint8_t*>>( 178 const std::string&, int, std::size_t)); 179 PDX_REMOTE_METHOD(PushChannel, kOpPushChannel, LocalChannelHandle(Void)); 180 PDX_REMOTE_METHOD(Positive, kOpPositive, void(int)); 181 182 PDX_REMOTE_API(API, Add, Foo, Concatenate, SumVector, StringLength, 183 SendTestType, SendVector, Rot13, NoArgs, SendFile, GetFile, 184 GetTestFdType, OpenFiles, PushChannel, Positive); 185}; 186 187constexpr char TestInterface::kClientPath[]; 188 189// Test client to send messages to the test service. 190class TestClient : public ClientBase<TestClient> { 191 public: 192 int Add(int a, int b) { 193 return ReturnStatusOrError(InvokeRemoteMethod<TestInterface::Add>(a, b)); 194 } 195 196 int Foo(int a, const std::string& b) { 197 return ReturnStatusOrError(InvokeRemoteMethod<TestInterface::Foo>(a, b)); 198 } 199 200 std::string Concatenate(const std::string& a, const std::string& b) { 201 std::string return_value; 202 203 Status<std::string> status = 204 InvokeRemoteMethod<TestInterface::Concatenate>(a, b); 205 if (!status) 206 return std::string("[Error]"); 207 else 208 return status.take(); 209 } 210 211 int SumVector(const int* buffer, std::size_t size) { 212 return ReturnStatusOrError( 213 InvokeRemoteMethod<TestInterface::SumVector>(WrapArray(buffer, size))); 214 } 215 216 int SumVector(const std::vector<int>& buffer) { 217 return ReturnStatusOrError( 218 InvokeRemoteMethod<TestInterface::SumVector>(buffer)); 219 } 220 221 int StringLength(const char* string, std::size_t size) { 222 return ReturnStatusOrError(InvokeRemoteMethod<TestInterface::StringLength>( 223 WrapString(string, size))); 224 } 225 226 int StringLength(const std::string& string) { 227 return ReturnStatusOrError( 228 InvokeRemoteMethod<TestInterface::StringLength>(string)); 229 } 230 231 TestType SendTestType(const TestType& tt) { 232 Status<TestType> status = 233 InvokeRemoteMethod<TestInterface::SendTestType>(tt); 234 if (!status) 235 return TestType(0, 0.0, "[Error]"); 236 else 237 return status.take(); 238 } 239 240 BasicStruct SendBasicStruct(const BasicStruct& bs) { 241 Status<BasicStruct> status = 242 InvokeRemoteMethod<TestInterface::SendBasicStruct>(bs); 243 if (!status) 244 return BasicStruct{0, 0, "[Error]"}; 245 else 246 return status.take(); 247 } 248 249 std::string SendVector(const std::vector<TestType>& v) { 250 Status<std::string> status = 251 InvokeRemoteMethod<TestInterface::SendVector>(v); 252 if (!status) 253 return "[Error]"; 254 else 255 return status.take(); 256 } 257 258 std::string Rot13(const std::string& string) { 259 Status<std::string> status = 260 InvokeRemoteMethod<TestInterface::Rot13>(string); 261 return status ? status.get() : string; 262 } 263 264 int NoArgs() { 265 return ReturnStatusOrError(InvokeRemoteMethod<TestInterface::NoArgs>()); 266 } 267 268 int SendFile(const LocalHandle& fd) { 269 return ReturnStatusOrError(InvokeRemoteMethod<TestInterface::SendFile>(fd)); 270 } 271 272 LocalHandle GetFile(const std::string& path, int mode) { 273 Status<LocalHandle> status = 274 InvokeRemoteMethod<TestInterface::GetFile>(path, mode); 275 if (!status) 276 return LocalHandle(-status.error()); 277 else 278 return status.take(); 279 } 280 281 int GetFile(const std::string& path, int mode, LocalHandle* fd_out) { 282 Status<void> status = 283 InvokeRemoteMethodInPlace<TestInterface::GetFile>(fd_out, path, mode); 284 return status ? 0 : -status.error(); 285 } 286 287 TestFdType GetTestFdType(int a, const std::string& path, int mode) { 288 Status<TestFdType> status = 289 InvokeRemoteMethod<TestInterface::GetTestFdType>(a, path, mode); 290 if (!status) 291 return {}; 292 else 293 return status.take(); 294 } 295 296 std::vector<LocalHandle> OpenFiles( 297 const std::vector<std::pair<std::string, int>>& file_specs) { 298 Status<std::vector<LocalHandle>> status = 299 InvokeRemoteMethod<TestInterface::OpenFiles>(file_specs); 300 if (!status) 301 return {}; 302 else 303 return status.take(); 304 } 305 306 int ReadFile(void* buffer, std::size_t size, const std::string& path, 307 int mode) { 308 auto buffer_wrapper = WrapBuffer(buffer, size); 309 auto return_value = std::make_pair(-1, buffer_wrapper); 310 311 Status<void> status = InvokeRemoteMethodInPlace<TestInterface::ReadFile>( 312 &return_value, path, mode, size); 313 return status ? return_value.first : -status.error(); 314 } 315 316 int PushChannel(LocalChannelHandle* fd_out) { 317 auto status = InvokeRemoteMethodInPlace<TestInterface::PushChannel>(fd_out); 318 return status ? 0 : -status.error(); 319 } 320 321 bool Positive(int test_value) { 322 auto status = InvokeRemoteMethod<TestInterface::Positive>(test_value); 323 return status.ok(); 324 } 325 326 int GetFd() const { return event_fd(); } 327 328 private: 329 friend BASE; 330 331 TestClient(LocalChannelHandle channel_handle) 332 : BASE{android::pdx::uds::ClientChannel::Create( 333 std::move(channel_handle))} {} 334 TestClient() 335 : BASE{android::pdx::uds::ClientChannelFactory::Create( 336 TestInterface::kClientPath)} {} 337 338 TestClient(const TestClient&) = delete; 339 void operator=(const TestClient&) = delete; 340}; 341 342// Test service that encodes/decodes messages from clients. 343class TestService : public ServiceBase<TestService> { 344 public: 345 Status<void> HandleMessage(Message& message) override { 346 switch (message.GetOp()) { 347 case TestInterface::Add::Opcode: 348 DispatchRemoteMethod<TestInterface::Add>(*this, &TestService::OnAdd, 349 message); 350 return {}; 351 352 case TestInterface::Foo::Opcode: 353 DispatchRemoteMethod<TestInterface::Foo>(*this, &TestService::OnFoo, 354 message); 355 return {}; 356 357 case TestInterface::Concatenate::Opcode: 358 DispatchRemoteMethod<TestInterface::Concatenate>( 359 *this, &TestService::OnConcatenate, message); 360 return {}; 361 362 case TestInterface::SumVector::Opcode: 363 DispatchRemoteMethod<TestInterface::SumVector>( 364 *this, &TestService::OnSumVector, message); 365 return {}; 366 367 case TestInterface::StringLength::Opcode: 368 DispatchRemoteMethod<TestInterface::StringLength>( 369 *this, &TestService::OnStringLength, message); 370 return {}; 371 372 case TestInterface::SendTestType::Opcode: 373 DispatchRemoteMethod<TestInterface::SendTestType>( 374 *this, &TestService::OnSendTestType, message); 375 return {}; 376 377 case TestInterface::SendVector::Opcode: 378 DispatchRemoteMethod<TestInterface::SendVector>( 379 *this, &TestService::OnSendVector, message); 380 return {}; 381 382 case TestInterface::Rot13::Opcode: 383 DispatchRemoteMethod<TestInterface::Rot13>(*this, &TestService::OnRot13, 384 message); 385 return {}; 386 387 case TestInterface::NoArgs::Opcode: 388 DispatchRemoteMethod<TestInterface::NoArgs>( 389 *this, &TestService::OnNoArgs, message); 390 return {}; 391 392 case TestInterface::SendFile::Opcode: 393 DispatchRemoteMethod<TestInterface::SendFile>( 394 *this, &TestService::OnSendFile, message); 395 return {}; 396 397 case TestInterface::GetFile::Opcode: 398 DispatchRemoteMethod<TestInterface::GetFile>( 399 *this, &TestService::OnGetFile, message); 400 return {}; 401 402 case TestInterface::GetTestFdType::Opcode: 403 DispatchRemoteMethod<TestInterface::GetTestFdType>( 404 *this, &TestService::OnGetTestFdType, message); 405 return {}; 406 407 case TestInterface::OpenFiles::Opcode: 408 DispatchRemoteMethod<TestInterface::OpenFiles>( 409 *this, &TestService::OnOpenFiles, message); 410 return {}; 411 412 case TestInterface::ReadFile::Opcode: 413 DispatchRemoteMethod<TestInterface::ReadFile>( 414 *this, &TestService::OnReadFile, message); 415 return {}; 416 417 case TestInterface::PushChannel::Opcode: 418 DispatchRemoteMethod<TestInterface::PushChannel>( 419 *this, &TestService::OnPushChannel, message); 420 return {}; 421 422 case TestInterface::Positive::Opcode: 423 DispatchRemoteMethod<TestInterface::Positive>( 424 *this, &TestService::OnPositive, message); 425 return {}; 426 427 default: 428 return Service::DefaultHandleMessage(message); 429 } 430 } 431 432 private: 433 friend BASE; 434 435 TestService() 436 : BASE("TestService", 437 Endpoint::CreateAndBindSocket(TestInterface::kClientPath)) {} 438 439 int OnAdd(Message&, int a, int b) { return a + b; } 440 441 int OnFoo(Message&, int a, const std::string& b) { return a + b.length(); } 442 443 std::string OnConcatenate(Message&, const std::string& a, 444 const std::string& b) { 445 return a + b; 446 } 447 448 int OnSumVector(Message&, const std::vector<int>& vector) { 449 return std::accumulate(vector.begin(), vector.end(), 0); 450 } 451 452 int OnStringLength(Message&, const std::string& string) { 453 return string.length(); 454 } 455 456 TestType OnSendTestType(Message&, const TestType& tt) { 457 return TestType(tt.a + 20, tt.b - 2.0, tt.c + "foo"); 458 } 459 460 std::string OnSendVector(Message&, const std::vector<TestType>& v) { 461 std::string return_value = ""; 462 463 for (const auto& tt : v) 464 return_value += tt.c; 465 466 return return_value; 467 } 468 469 Status<std::string> OnRot13(Message&, const std::string& s) { 470 return {Rot13(s)}; 471 } 472 473 int OnNoArgs(Message&) { return 1; } 474 475 int OnSendFile(Message&, const LocalHandle& fd) { return fd.Get(); } 476 477 LocalHandle OnGetFile(Message& message, const std::string& path, int mode) { 478 LocalHandle fd(path.c_str(), mode); 479 if (!fd) 480 message.ReplyError(errno); 481 return fd; 482 } 483 484 TestFdType OnGetTestFdType(Message& message, int a, const std::string& path, 485 int mode) { 486 TestFdType return_value(a, LocalHandle(path, mode)); 487 if (!return_value.fd) 488 message.ReplyError(errno); 489 return return_value; 490 } 491 492 std::vector<LocalHandle> OnOpenFiles( 493 Message&, const std::vector<std::pair<std::string, int>>& file_specs) { 494 std::vector<LocalHandle> return_value; 495 for (auto& spec : file_specs) { 496 LocalHandle fd(spec.first, spec.second); 497 if (fd) 498 return_value.emplace_back(std::move(fd)); 499 else 500 return_value.emplace_back(-errno); 501 } 502 return return_value; 503 } 504 505 std::pair<int, BufferWrapper<std::vector<std::uint8_t>>> OnReadFile( 506 Message& message, const std::string& path, int mode, std::size_t length) { 507 std::pair<int, BufferWrapper<std::vector<std::uint8_t>>> return_value; 508 LocalHandle fd(path, mode); 509 if (!fd) { 510 message.ReplyError(errno); 511 return return_value; 512 } 513 514 return_value.second.reserve(length); 515 const int ret = read(fd.Get(), return_value.second.data(), length); 516 if (ret < 0) { 517 message.ReplyError(errno); 518 return return_value; 519 } 520 521 return_value.second.resize(ret); 522 return_value.first = ret; 523 return return_value; 524 } 525 526 RemoteChannelHandle OnPushChannel(Message& message) { 527 auto status = message.PushChannel(0, nullptr, nullptr); 528 if (!status) { 529 message.ReplyError(status.error()); 530 return {}; 531 } 532 return status.take(); 533 } 534 535 Status<void> OnPositive(Message& /*message*/, int test_value) { 536 if (test_value >= 0) 537 return {}; 538 else 539 return ErrorStatus(EINVAL); 540 } 541 542 TestService(const TestService&) = delete; 543 void operator=(const TestService&) = delete; 544}; 545 546} // anonymous namespace 547 548// Use a test fixture to ensure proper order of cleanup between clients, 549// services, and the dispatcher. As these objects are cleaned up in the same 550// thread, either the service or client must be destroyed before stopping the 551// dispatcher. The reason for this is that clients send blocking "close" 552// messages to their respective services on destruction. If this happens after 553// stopping the dispatcher the client destructor will get blocked waiting for a 554// reply that will never come. In normal use of the service framework this is 555// never an issue because clients and the dispatcher for the same service are 556// never destructed in the same thread (they live in different processes). 557class RemoteMethodTest : public ::testing::Test { 558 protected: 559 std::unique_ptr<ServiceDispatcher> dispatcher_; 560 std::thread dispatch_thread_; 561 562 void SetUp() override { 563 // Create a dispatcher to handle messages to services. 564 dispatcher_ = android::pdx::ServiceDispatcher::Create(); 565 ASSERT_NE(nullptr, dispatcher_); 566 567 // Start the message dispatch loop in a separate thread. 568 dispatch_thread_ = std::thread( 569 std::bind(&ServiceDispatcher::EnterDispatchLoop, dispatcher_.get())); 570 } 571 572 void TearDown() override { 573 if (dispatcher_) { 574 // Cancel the dispatcher and wait for the thread to terminate. 575 // Explicitly 576 // join the thread so that destruction doesn't deallocate the 577 // dispatcher 578 // before the thread finishes. 579 dispatcher_->SetCanceled(true); 580 dispatch_thread_.join(); 581 } 582 } 583}; 584 585// Test basic operation of TestService/TestClient classes. 586TEST_F(RemoteMethodTest, BasicClientService) { 587 // Create a test service and add it to the dispatcher. 588 589 auto service = TestService::Create(); 590 ASSERT_NE(nullptr, service); 591 ASSERT_EQ(0, dispatcher_->AddService(service)); 592 593 // Create a client to service. 594 auto client = TestClient::Create(); 595 ASSERT_NE(nullptr, client); 596 597 const int sum = client->Add(10, 25); 598 EXPECT_GE(35, sum); 599 600 const auto cat = client->Concatenate("This is a string", ", that it is."); 601 EXPECT_EQ("This is a string, that it is.", cat); 602 603 std::string alphabet = "abcdefghijklmnopqrstuvwxyz"; 604 const auto rot13_alphabet = client->Rot13(alphabet); 605 EXPECT_EQ(Rot13(alphabet), rot13_alphabet); 606 607 const auto length = client->Foo(10, "123"); 608 EXPECT_EQ(13, length); 609 610 const std::vector<int> vector{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 611 const int vector_sum = client->SumVector(vector.data(), vector.size()); 612 const int vector_sum2 = client->SumVector(vector); 613 EXPECT_EQ(std::accumulate(vector.begin(), vector.end(), 0), vector_sum); 614 EXPECT_EQ(std::accumulate(vector.begin(), vector.end(), 0), vector_sum2); 615 616 const auto string_length1 = client->StringLength("This is a string"); 617 EXPECT_EQ(16, string_length1); 618 619 const auto string_length2 = client->StringLength("1234567890"); 620 EXPECT_EQ(10, string_length2); 621 622 std::string string = "1234567890"; 623 const auto string_length3 = 624 client->StringLength(string.c_str(), string.length()); 625 EXPECT_EQ(10, string_length3); 626 627 TestType tt{10, 0.0, "string"}; 628 const auto tt_result = client->SendTestType(tt); 629 EXPECT_EQ(TestType(30, -2.0, "stringfoo"), tt_result); 630 631 std::vector<TestType> ttv = {TestType(0, 0.0, "abc"), 632 TestType(0, 0.0, "123")}; 633 const std::string string_result = client->SendVector(ttv); 634 EXPECT_EQ("abc123", string_result); 635 636 const int int_result = client->NoArgs(); 637 EXPECT_EQ(1, int_result); 638} 639 640TEST_F(RemoteMethodTest, LocalHandle) { 641 // Create a test service and add it to the dispatcher. 642 auto service = TestService::Create(); 643 ASSERT_NE(nullptr, service); 644 ASSERT_EQ(0, dispatcher_->AddService(service)); 645 646 // Create a client to service. 647 auto client = TestClient::Create(); 648 ASSERT_NE(nullptr, client); 649 650 LocalHandle fd("/dev/zero", O_RDONLY); 651 ASSERT_TRUE(fd.IsValid()); 652 653 int fd_result = client->SendFile(fd); 654 EXPECT_LE(0, fd_result); 655 EXPECT_NE(fd.Get(), fd_result); 656 fd = LocalHandle(-3); 657 fd_result = client->SendFile(fd); 658 EXPECT_EQ(fd.Get(), fd_result); 659 660 fd = client->GetFile("/dev/zero", O_RDONLY); 661 ASSERT_TRUE(fd.IsValid()) << "Error code: " << fd.Get(); 662 663 std::array<uint8_t, 10> buffer; 664 buffer.fill(1); 665 EXPECT_EQ(10, read(fd.Get(), buffer.data(), buffer.size())); 666 EXPECT_EQ(buffer, decltype(buffer){{0}}); 667 fd.Close(); 668 669 const int error = client->GetFile("/dev/zero", O_RDONLY, &fd); 670 EXPECT_EQ(0, error); 671 EXPECT_TRUE(fd.IsValid()); 672 673 buffer.fill(1); 674 EXPECT_EQ(10, read(fd.Get(), buffer.data(), buffer.size())); 675 EXPECT_EQ(buffer, decltype(buffer){{0}}); 676 677 /* 678 Seg fault. 679 fd = client->GetFile("/dev/foobar", O_RDONLY); 680 EXPECT_FALSE(fd.IsValid()); 681 */ 682} 683 684TEST_F(RemoteMethodTest, PushChannel) { 685 // Create a test service and add it to the dispatcher. 686 auto service = TestService::Create(); 687 ASSERT_NE(nullptr, service); 688 ASSERT_EQ(0, dispatcher_->AddService(service)); 689 690 // Create a client to service. 691 auto client = TestClient::Create(); 692 ASSERT_NE(nullptr, client); 693 694 // Get a new channel as an fd. 695 LocalChannelHandle channel; 696 const int ret = client->PushChannel(&channel); 697 EXPECT_EQ(0, ret); 698 EXPECT_TRUE(channel.valid()); 699 700 // Create a new client from the channel. 701 auto client2 = TestClient::Create(std::move(channel)); 702 ASSERT_NE(nullptr, client2); 703 704 // Test that the new channel works. 705 const int sum = client2->Add(10, 25); 706 EXPECT_GE(35, sum); 707} 708 709TEST_F(RemoteMethodTest, Positive) { 710 // Create a test service and add it to the dispatcher. 711 auto service = TestService::Create(); 712 ASSERT_NE(nullptr, service); 713 ASSERT_EQ(0, dispatcher_->AddService(service)); 714 715 // Create a client to service. 716 auto client = TestClient::Create(); 717 ASSERT_NE(nullptr, client); 718 719 ASSERT_TRUE(client->Positive(0)); 720 ASSERT_TRUE(client->Positive(1)); 721 ASSERT_FALSE(client->Positive(-1)); 722} 723 724TEST_F(RemoteMethodTest, AggregateLocalHandle) { 725 // Create a test service and add it to the dispatcher. 726 auto service = TestService::Create(); 727 ASSERT_NE(nullptr, service); 728 ASSERT_EQ(0, dispatcher_->AddService(service)); 729 730 // Create a client to service. 731 auto client = TestClient::Create(); 732 ASSERT_NE(nullptr, client); 733 734 TestFdType result = client->GetTestFdType(10, "/dev/zero", O_RDONLY); 735 EXPECT_TRUE(result.fd.IsValid()); 736 EXPECT_EQ(10, result.a); 737 738 std::vector<LocalHandle> files = 739 client->OpenFiles({{{"/dev/zero", O_RDONLY}, 740 {"/dev/null", O_WRONLY}, 741 {"/dev/zero", O_RDONLY}}}); 742 ASSERT_EQ(3u, files.size()); 743 EXPECT_TRUE(files[0].IsValid()); 744 EXPECT_TRUE(files[1].IsValid()); 745 EXPECT_TRUE(files[2].IsValid()); 746} 747 748TEST_F(RemoteMethodTest, BufferWrapper) { 749 // Create a test service and add it to the dispatcher. 750 auto service = TestService::Create(); 751 ASSERT_NE(nullptr, service); 752 ASSERT_EQ(0, dispatcher_->AddService(service)); 753 754 // Create a client to service. 755 auto client = TestClient::Create(); 756 ASSERT_NE(nullptr, client); 757 758 const int buffer_size = 20; 759 std::vector<std::uint8_t> buffer(buffer_size, 'x'); 760 std::vector<std::uint8_t> expected(buffer_size, 0); 761 int ret = 762 client->ReadFile(buffer.data(), buffer.size(), "/dev/zero", O_RDONLY); 763 EXPECT_EQ(buffer_size, ret); 764 EXPECT_EQ(expected, buffer); 765} 766 767// 768// RemoteMethodFramework: Tests the type-based framework that remote method 769// support is built upon. 770// 771 772// Test logical And template. 773TEST(RemoteMethodFramework, And) { 774 EXPECT_TRUE((And<std::true_type, std::true_type>::value)); 775 EXPECT_FALSE((And<std::true_type, std::false_type>::value)); 776 EXPECT_FALSE((And<std::false_type, std::true_type>::value)); 777 EXPECT_FALSE((And<std::false_type, std::false_type>::value)); 778 779 EXPECT_TRUE((And<std::true_type, std::true_type, std::true_type>::value)); 780 EXPECT_FALSE((And<std::true_type, std::true_type, std::false_type>::value)); 781 EXPECT_FALSE((And<std::true_type, std::false_type, std::true_type>::value)); 782 EXPECT_FALSE((And<std::true_type, std::false_type, std::false_type>::value)); 783 EXPECT_FALSE((And<std::false_type, std::true_type, std::true_type>::value)); 784 EXPECT_FALSE((And<std::false_type, std::true_type, std::false_type>::value)); 785 EXPECT_FALSE((And<std::false_type, std::false_type, std::true_type>::value)); 786 EXPECT_FALSE((And<std::false_type, std::false_type, std::false_type>::value)); 787} 788 789// Test convertible type constraints. 790TEST(RemoteMethodFramework, IsConvertible) { 791 // std::pair. 792 EXPECT_TRUE( 793 (IsConvertible<std::pair<int, float>, std::pair<int, float>>::value)); 794 EXPECT_FALSE( 795 (IsConvertible<std::pair<int, float>, std::pair<float, float>>::value)); 796 EXPECT_FALSE( 797 (IsConvertible<std::pair<int, float>, std::pair<float, int>>::value)); 798 799 // Nested std::pair. 800 EXPECT_TRUE((IsConvertible<std::pair<std::pair<int, float>, float>, 801 std::pair<std::pair<int, float>, float>>::value)); 802 EXPECT_FALSE((IsConvertible<std::pair<std::pair<int, float>, float>, 803 std::pair<std::pair<float, int>, float>>::value)); 804 805 // std::tuple and std::pair. 806 EXPECT_TRUE( 807 (IsConvertible<std::pair<int, float>, std::tuple<int, float>>::value)); 808 EXPECT_TRUE( 809 (IsConvertible<std::tuple<int, float>, std::pair<int, float>>::value)); 810 EXPECT_FALSE( 811 (IsConvertible<std::pair<float, float>, std::tuple<int, float>>::value)); 812 EXPECT_FALSE( 813 (IsConvertible<std::tuple<float, float>, std::pair<int, float>>::value)); 814 EXPECT_FALSE( 815 (IsConvertible<std::pair<int, int>, std::tuple<int, float>>::value)); 816 EXPECT_FALSE( 817 (IsConvertible<std::tuple<int, int>, std::pair<int, float>>::value)); 818 EXPECT_FALSE( 819 (IsConvertible<std::pair<int, int>, std::tuple<int, int, int>>::value)); 820 EXPECT_FALSE( 821 (IsConvertible<std::tuple<int, int, int>, std::pair<int, int>>::value)); 822 823 // std::vector. 824 EXPECT_TRUE((IsConvertible<std::vector<int>, std::vector<int>>::value)); 825 EXPECT_FALSE((IsConvertible<std::vector<int>, std::vector<float>>::value)); 826 827 // Nested std::vector. 828 EXPECT_TRUE((IsConvertible<std::vector<std::pair<int, int>>, 829 std::vector<std::pair<int, int>>>::value)); 830 EXPECT_FALSE((IsConvertible<std::vector<std::pair<int, int>>, 831 std::vector<std::pair<int, float>>>::value)); 832 EXPECT_FALSE((IsConvertible<std::vector<std::pair<int, int>>, 833 std::vector<std::pair<float, int>>>::value)); 834 EXPECT_FALSE((IsConvertible<std::vector<std::pair<int, int>>, 835 std::vector<std::pair<float, float>>>::value)); 836 837 // std::vector with nested convertible types. 838 EXPECT_TRUE((IsConvertible<std::vector<StringWrapper<char>>, 839 std::vector<std::string>>::value)); 840 841 // std::map and std::unordered_map. 842 EXPECT_TRUE((IsConvertible<std::map<int, float>, 843 std::unordered_map<int, float>>::value)); 844 EXPECT_FALSE((IsConvertible<std::map<float, float>, 845 std::unordered_map<int, float>>::value)); 846 EXPECT_FALSE((IsConvertible<std::map<float, float>, 847 std::unordered_map<float, int>>::value)); 848 EXPECT_FALSE((IsConvertible<std::map<float, float>, 849 std::unordered_map<int, int>>::value)); 850 EXPECT_TRUE((IsConvertible<std::unordered_map<int, float>, 851 std::map<int, float>>::value)); 852 EXPECT_FALSE((IsConvertible<std::unordered_map<float, float>, 853 std::map<int, float>>::value)); 854 EXPECT_FALSE((IsConvertible<std::unordered_map<float, float>, 855 std::map<float, int>>::value)); 856 EXPECT_FALSE((IsConvertible<std::unordered_map<float, float>, 857 std::map<int, int>>::value)); 858 859 // std::map with nested convertible types. 860 EXPECT_TRUE((IsConvertible<std::map<int, std::string>, 861 std::map<int, StringWrapper<char>>>::value)); 862 EXPECT_TRUE( 863 (IsConvertible<std::map<std::tuple<int, int>, std::string>, 864 std::map<std::pair<int, int>, std::string>>::value)); 865 866 // std::unordered_map with nested convertible types. 867 EXPECT_TRUE( 868 (IsConvertible<std::unordered_map<int, std::string>, 869 std::unordered_map<int, StringWrapper<char>>>::value)); 870 EXPECT_TRUE((IsConvertible< 871 std::unordered_map<std::tuple<int, int>, std::string>, 872 std::unordered_map<std::pair<int, int>, std::string>>::value)); 873 874 // std::string. 875 EXPECT_TRUE((IsConvertible<std::string, std::string>::value)); 876 EXPECT_FALSE((IsConvertible<std::string, int>::value)); 877 EXPECT_FALSE((IsConvertible<int, std::string>::value)); 878 879 // Nested std::string. 880 EXPECT_TRUE((IsConvertible<std::pair<std::string, std::string>, 881 std::pair<std::string, std::string>>::value)); 882 EXPECT_FALSE((IsConvertible<std::pair<std::string, std::string>, 883 std::pair<std::string, int>>::value)); 884 EXPECT_FALSE((IsConvertible<std::pair<std::string, std::string>, 885 std::pair<int, std::string>>::value)); 886 EXPECT_FALSE((IsConvertible<std::pair<std::string, std::string>, 887 std::pair<int, int>>::value)); 888 889 // StringWrapper. 890 EXPECT_TRUE((IsConvertible<StringWrapper<char>, StringWrapper<char>>::value)); 891 EXPECT_TRUE((IsConvertible<StringWrapper<char>, std::string>::value)); 892 EXPECT_TRUE((IsConvertible<std::string, StringWrapper<char>>::value)); 893 EXPECT_FALSE((IsConvertible<StringWrapper<char>, int>::value)); 894 EXPECT_FALSE( 895 (IsConvertible<StringWrapper<char>, BufferWrapper<char*>>::value)); 896 897 // BufferWrapper. 898 EXPECT_TRUE( 899 (IsConvertible<BufferWrapper<char*>, BufferWrapper<char*>>::value)); 900 EXPECT_TRUE( 901 (IsConvertible<BufferWrapper<char*>, BufferWrapper<const char*>>::value)); 902 EXPECT_FALSE( 903 (IsConvertible<BufferWrapper<char*>, BufferWrapper<int*>>::value)); 904 EXPECT_TRUE((IsConvertible<BufferWrapper<char*>, 905 BufferWrapper<std::vector<char>>>::value)); 906 907 // RemoteHandle and BorrowedHandle. 908 EXPECT_TRUE((IsConvertible<LocalHandle, RemoteHandle>::value)); 909 EXPECT_TRUE((IsConvertible<LocalHandle, BorrowedHandle>::value)); 910 911 // Test rewriting user defined types. 912 EXPECT_TRUE((IsConvertible<TestTemplateType<LocalHandle>, 913 TestTemplateType<RemoteHandle>>::value)); 914 EXPECT_TRUE((IsConvertible<TestTemplateType<LocalHandle>, 915 TestTemplateType<BorrowedHandle>>::value)); 916 EXPECT_FALSE((IsConvertible<TestTemplateType<RemoteHandle>, 917 TestTemplateType<LocalHandle>>::value)); 918 EXPECT_FALSE((IsConvertible<TestTemplateType<BorrowedHandle>, 919 TestTemplateType<LocalHandle>>::value)); 920 921 // TODO(eieio): More thorough testing of convertible types. 922} 923 924TEST(RemoteMethodFramework, SerializableMembers) { 925 EXPECT_TRUE(HasSerializableMembers<TestTemplateType<LocalHandle>>::value); 926 EXPECT_TRUE(HasSerializableMembers<TestTemplateType<RemoteHandle>>::value); 927 EXPECT_TRUE(HasSerializableMembers<TestTemplateType<BorrowedHandle>>::value); 928 929 EXPECT_TRUE(std::is_void<EnableIfHasSerializableMembers< 930 TestTemplateType<LocalHandle>>>::value); 931 EXPECT_TRUE(std::is_void<EnableIfHasSerializableMembers< 932 TestTemplateType<RemoteHandle>>>::value); 933 EXPECT_TRUE(std::is_void<EnableIfHasSerializableMembers< 934 TestTemplateType<BorrowedHandle>>>::value); 935 936 EXPECT_TRUE(HasSerializableMembers<DerivedTestType>::value); 937 938 EXPECT_TRUE(HasSerializableMembers<BasicStruct>::value); 939 EXPECT_TRUE(HasSerializableMembers<TestType>::value); 940 EXPECT_TRUE(HasSerializableMembers<TestTemplateType<LocalHandle>>::value); 941 EXPECT_TRUE(HasSerializableMembers<TestTemplateType<RemoteHandle>>::value); 942 EXPECT_TRUE(HasSerializableMembers<TestTemplateType<BorrowedHandle>>::value); 943 EXPECT_TRUE(HasSerializableMembers<DerivedTestType>::value); 944 EXPECT_FALSE(HasSerializableMembers<NonSerializableType>::value); 945 EXPECT_FALSE( 946 HasSerializableMembers<IncorrectlyDefinedSerializableType>::value); 947} 948 949TEST(RemoteMethodFramework, RemoteAPITypes) { 950 EXPECT_EQ(0u, TestInterface::API::MethodIndex<TestInterface::Add>()); 951} 952