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