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