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