• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
23 using android::pdx::BorrowedHandle;
24 using android::pdx::Channel;
25 using android::pdx::ClientBase;
26 using android::pdx::ErrorStatus;
27 using android::pdx::LocalChannelHandle;
28 using android::pdx::LocalHandle;
29 using android::pdx::Message;
30 using android::pdx::RemoteChannelHandle;
31 using android::pdx::RemoteHandle;
32 using android::pdx::ServiceBase;
33 using android::pdx::ServiceDispatcher;
34 using android::pdx::Status;
35 using android::pdx::uds::Endpoint;
36 using namespace android::pdx::rpc;
37 
38 namespace {
39 
Rot13(const std::string & s)40 std::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.
56 struct TestType {
57   int a;
58   float b;
59   std::string c;
60 
TestType__anon414d72a00111::TestType61   TestType() {}
TestType__anon414d72a00111::TestType62   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.
operator ==__anon414d72a00111::TestType66   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 
74 struct DerivedTestType : public TestType {
DerivedTestType__anon414d72a00111::DerivedTestType75   DerivedTestType() : TestType() {}
DerivedTestType__anon414d72a00111::DerivedTestType76   DerivedTestType(int a, float b) : TestType(a, b, "constant") {}
77 };
78 
79 // Defines a serializable user type with a LocalHandle member.
80 struct TestFdType {
81   int a;
82   LocalHandle fd;
83 
TestFdType__anon414d72a00111::TestFdType84   TestFdType() {}
TestFdType__anon414d72a00111::TestFdType85   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.
92 template <typename FileHandleType>
93 struct TestTemplateType {
94   FileHandleType fd;
95 
TestTemplateType__anon414d72a00111::TestTemplateType96   TestTemplateType() {}
TestTemplateType__anon414d72a00111::TestTemplateType97   TestTemplateType(FileHandleType fd) : fd(std::move(fd)) {}
98 
99  private:
100   PDX_SERIALIZABLE_MEMBERS(TestTemplateType<FileHandleType>, fd);
101 };
102 
103 struct BasicStruct {
104   int a;
105   int b;
106   std::string c;
107 
108  private:
109   PDX_SERIALIZABLE_MEMBERS(BasicStruct, a, b, c);
110 };
111 
112 using BasicStructTraits = SerializableTraits<BasicStruct>;
113 
114 struct NonSerializableType {
115   int a;
116   int b;
117   std::string c;
118 };
119 
120 struct 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.
130 struct 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 
187 constexpr char TestInterface::kClientPath[];
188 
189 // Test client to send messages to the test service.
190 class TestClient : public ClientBase<TestClient> {
191  public:
Add(int a,int b)192   int Add(int a, int b) {
193     return ReturnStatusOrError(InvokeRemoteMethod<TestInterface::Add>(a, b));
194   }
195 
Foo(int a,const std::string & b)196   int Foo(int a, const std::string& b) {
197     return ReturnStatusOrError(InvokeRemoteMethod<TestInterface::Foo>(a, b));
198   }
199 
Concatenate(const std::string & a,const std::string & b)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 
SumVector(const int * buffer,std::size_t size)211   int SumVector(const int* buffer, std::size_t size) {
212     return ReturnStatusOrError(
213         InvokeRemoteMethod<TestInterface::SumVector>(WrapArray(buffer, size)));
214   }
215 
SumVector(const std::vector<int> & buffer)216   int SumVector(const std::vector<int>& buffer) {
217     return ReturnStatusOrError(
218         InvokeRemoteMethod<TestInterface::SumVector>(buffer));
219   }
220 
StringLength(const char * string,std::size_t size)221   int StringLength(const char* string, std::size_t size) {
222     return ReturnStatusOrError(InvokeRemoteMethod<TestInterface::StringLength>(
223         WrapString(string, size)));
224   }
225 
StringLength(const std::string & string)226   int StringLength(const std::string& string) {
227     return ReturnStatusOrError(
228         InvokeRemoteMethod<TestInterface::StringLength>(string));
229   }
230 
SendTestType(const TestType & tt)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 
SendBasicStruct(const BasicStruct & bs)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 
SendVector(const std::vector<TestType> & v)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 
Rot13(const std::string & string)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 
NoArgs()264   int NoArgs() {
265     return ReturnStatusOrError(InvokeRemoteMethod<TestInterface::NoArgs>());
266   }
267 
SendFile(const LocalHandle & fd)268   int SendFile(const LocalHandle& fd) {
269     return ReturnStatusOrError(InvokeRemoteMethod<TestInterface::SendFile>(fd));
270   }
271 
GetFile(const std::string & path,int mode)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 
GetFile(const std::string & path,int mode,LocalHandle * fd_out)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 
GetTestFdType(int a,const std::string & path,int mode)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 
OpenFiles(const std::vector<std::pair<std::string,int>> & file_specs)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 
ReadFile(void * buffer,std::size_t size,const std::string & path,int mode)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 
PushChannel(LocalChannelHandle * fd_out)316   int PushChannel(LocalChannelHandle* fd_out) {
317     auto status = InvokeRemoteMethodInPlace<TestInterface::PushChannel>(fd_out);
318     return status ? 0 : -status.error();
319   }
320 
Positive(int test_value)321   bool Positive(int test_value) {
322     auto status = InvokeRemoteMethod<TestInterface::Positive>(test_value);
323     return status.ok();
324   }
325 
GetFd() const326   int GetFd() const { return event_fd(); }
327 
328  private:
329   friend BASE;
330 
TestClient(LocalChannelHandle channel_handle)331   TestClient(LocalChannelHandle channel_handle)
332       : BASE{android::pdx::uds::ClientChannel::Create(
333             std::move(channel_handle))} {}
TestClient()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.
343 class TestService : public ServiceBase<TestService> {
344  public:
HandleMessage(Message & message)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 
TestService()435   TestService()
436       : BASE("TestService",
437              Endpoint::CreateAndBindSocket(TestInterface::kClientPath)) {}
438 
OnAdd(Message &,int a,int b)439   int OnAdd(Message&, int a, int b) { return a + b; }
440 
OnFoo(Message &,int a,const std::string & b)441   int OnFoo(Message&, int a, const std::string& b) { return a + b.length(); }
442 
OnConcatenate(Message &,const std::string & a,const std::string & b)443   std::string OnConcatenate(Message&, const std::string& a,
444                             const std::string& b) {
445     return a + b;
446   }
447 
OnSumVector(Message &,const std::vector<int> & vector)448   int OnSumVector(Message&, const std::vector<int>& vector) {
449     return std::accumulate(vector.begin(), vector.end(), 0);
450   }
451 
OnStringLength(Message &,const std::string & string)452   int OnStringLength(Message&, const std::string& string) {
453     return string.length();
454   }
455 
OnSendTestType(Message &,const TestType & tt)456   TestType OnSendTestType(Message&, const TestType& tt) {
457     return TestType(tt.a + 20, tt.b - 2.0, tt.c + "foo");
458   }
459 
OnSendVector(Message &,const std::vector<TestType> & v)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 
OnRot13(Message &,const std::string & s)469   Status<std::string> OnRot13(Message&, const std::string& s) {
470     return {Rot13(s)};
471   }
472 
OnNoArgs(Message &)473   int OnNoArgs(Message&) { return 1; }
474 
OnSendFile(Message &,const LocalHandle & fd)475   int OnSendFile(Message&, const LocalHandle& fd) { return fd.Get(); }
476 
OnGetFile(Message & message,const std::string & path,int mode)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 
OnGetTestFdType(Message & message,int a,const std::string & path,int mode)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 
OnOpenFiles(Message &,const std::vector<std::pair<std::string,int>> & file_specs)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 
OnReadFile(Message & message,const std::string & path,int mode,std::size_t length)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 
OnPushChannel(Message & message)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 
OnPositive(Message &,int test_value)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).
557 class RemoteMethodTest : public ::testing::Test {
558  protected:
559   std::unique_ptr<ServiceDispatcher> dispatcher_;
560   std::thread dispatch_thread_;
561 
SetUp()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 
TearDown()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.
TEST_F(RemoteMethodTest,BasicClientService)586 TEST_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 
TEST_F(RemoteMethodTest,LocalHandle)640 TEST_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 
TEST_F(RemoteMethodTest,PushChannel)684 TEST_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 
TEST_F(RemoteMethodTest,Positive)709 TEST_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 
TEST_F(RemoteMethodTest,AggregateLocalHandle)724 TEST_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 
TEST_F(RemoteMethodTest,BufferWrapper)748 TEST_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.
TEST(RemoteMethodFramework,And)773 TEST(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.
TEST(RemoteMethodFramework,IsConvertible)790 TEST(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 
TEST(RemoteMethodFramework,SerializableMembers)924 TEST(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 
TEST(RemoteMethodFramework,RemoteAPITypes)949 TEST(RemoteMethodFramework, RemoteAPITypes) {
950   EXPECT_EQ(0u, TestInterface::API::MethodIndex<TestInterface::Add>());
951 }
952