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 <uds/client_channel.h>
19#include <uds/client_channel_factory.h>
20#include <uds/service_dispatcher.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::uds::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