1e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <errno.h> 2e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <fcntl.h> 352ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka#include <poll.h> 4e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <sys/epoll.h> 5e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <sys/eventfd.h> 6e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <unistd.h> 7e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 8e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <array> 9e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <atomic> 10e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <memory> 11e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <numeric> 12e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <string> 13e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <thread> 14e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 15e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <gtest/gtest.h> 16e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <pdx/channel_handle.h> 17e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <pdx/client.h> 18e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <pdx/file_handle.h> 19e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <pdx/service.h> 205a244ed36c8e45fd95b89ff916caf083fb182ec1Alex Vakulenko#include <pdx/service_dispatcher.h> 21e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <private/android_filesystem_config.h> 22e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <uds/client_channel.h> 23e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <uds/client_channel_factory.h> 24e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko#include <uds/service_endpoint.h> 25e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 26e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::BorrowedChannelHandle; 27e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::Channel; 28e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::ChannelReference; 29e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::ClientBase; 30186d77217aaf769ff0a91753971e23bd249afca7Corey Tabakausing android::pdx::ErrorStatus; 31e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::LocalChannelHandle; 32e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::LocalHandle; 33e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::Message; 34e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::MessageInfo; 35e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::RemoteChannelHandle; 36e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::ServiceBase; 37e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::ServiceDispatcher; 38e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::Status; 39e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::Transaction; 40e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing android::pdx::uds::Endpoint; 41e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 42e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkonamespace { 43e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 44e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoconst size_t kLargeDataSize = 100000; 45e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 46e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoconst char kTestServicePath[] = "socket_test"; 47e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoconst char kTestService1[] = "1"; 48e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoconst char kTestService2[] = "2"; 49e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 50e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoenum test_op_codes { 51e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko TEST_OP_GET_SERVICE_ID, 52e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko TEST_OP_SET_TEST_CHANNEL, 53e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko TEST_OP_GET_THIS_CHANNEL_ID, 54e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko TEST_OP_GET_TEST_CHANNEL_ID, 55e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko TEST_OP_CHECK_CHANNEL_ID, 56e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko TEST_OP_CHECK_CHANNEL_OBJECT, 57e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko TEST_OP_CHECK_CHANNEL_FROM_OTHER_SERVICE, 58e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko TEST_OP_GET_NEW_CHANNEL, 59e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko TEST_OP_GET_NEW_CHANNEL_FROM_OTHER_SERVICE, 60e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko TEST_OP_GET_THIS_PROCESS_ID, 61e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko TEST_OP_GET_THIS_THREAD_ID, 62e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko TEST_OP_GET_THIS_EUID, 63e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko TEST_OP_GET_THIS_EGID, 64e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko TEST_OP_IMPULSE, 65e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko TEST_OP_POLLHUP_FROM_SERVICE, 66e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko TEST_OP_POLLIN_FROM_SERVICE, 67e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko TEST_OP_SEND_LARGE_DATA_RETURN_SUM, 68e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}; 69e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 70e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkousing ImpulsePayload = std::array<std::uint8_t, sizeof(MessageInfo::impulse)>; 71e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 72e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// The test service creates a TestChannel for every client (channel) that 73e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// connects. This represents the service-side context for each client. 74e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoclass TestChannel : public Channel { 75e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko public: 76e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko explicit TestChannel(int channel_id) : channel_id_(channel_id) {} 77e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 78e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int channel_id() const { return channel_id_; } 79e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 80e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko private: 81e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko friend class TestService; 82e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 83e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int channel_id_; 84e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 85e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko TestChannel(const TestChannel&) = delete; 86e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko void operator=(const TestChannel&) = delete; 87e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}; 88e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 89e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Test service that creates a TestChannel for each channel and responds to test 90e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// messages. 91e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoclass TestService : public ServiceBase<TestService> { 92e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko public: 93e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::shared_ptr<Channel> OnChannelOpen(Message& message) override { 94e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return std::make_shared<TestChannel>(message.GetChannelId()); 95e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 96e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 97e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko void OnChannelClose(Message& /*message*/, 98e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const std::shared_ptr<Channel>& channel) override { 99e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (test_channel_ == channel) 100e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko test_channel_ = nullptr; 101e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 102e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 103e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko void HandleImpulse(Message& message) override { 104e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko switch (message.GetOp()) { 105e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko case TEST_OP_SET_TEST_CHANNEL: 106e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko test_channel_ = message.GetChannel<TestChannel>(); 107e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko break; 108e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 109e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko case TEST_OP_IMPULSE: { 110e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko impulse_payload_.fill(0); 111e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::copy(message.ImpulseBegin(), message.ImpulseEnd(), 112e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko impulse_payload_.begin()); 113e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko break; 114e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 115e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 116e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko case TEST_OP_POLLHUP_FROM_SERVICE: { 117e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko message.ModifyChannelEvents(0, EPOLLHUP); 118e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko break; 119e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 120e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 121e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 122e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 123f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko Status<void> HandleMessage(Message& message) override { 124e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko switch (message.GetOp()) { 125e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko case TEST_OP_GET_SERVICE_ID: 126f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko REPLY_MESSAGE_RETURN(message, service_id_, {}); 127e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 128e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Set the test channel to the TestChannel for the current channel. Other 129e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // messages can use this to perform tests. 130e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko case TEST_OP_SET_TEST_CHANNEL: 131e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko test_channel_ = message.GetChannel<TestChannel>(); 132f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko REPLY_MESSAGE_RETURN(message, 0, {}); 133e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 134e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Return the channel id for the current channel. 135e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko case TEST_OP_GET_THIS_CHANNEL_ID: 136f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko REPLY_MESSAGE_RETURN(message, message.GetChannelId(), {}); 137e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 138e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Return the channel id for the test channel. 139e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko case TEST_OP_GET_TEST_CHANNEL_ID: 140e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (test_channel_) 141f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko REPLY_MESSAGE_RETURN(message, test_channel_->channel_id(), {}); 142e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko else 143f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko REPLY_ERROR_RETURN(message, ENOENT, {}); 144e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 145e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Test check channel feature. 146e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko case TEST_OP_CHECK_CHANNEL_ID: { 147e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ChannelReference ref = 0; 148f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko if (!message.ReadAll(&ref, sizeof(ref))) 149f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko REPLY_ERROR_RETURN(message, EIO, {}); 150e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 151e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const Status<int> ret = message.CheckChannel<TestChannel>(ref, nullptr); 152f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko REPLY_MESSAGE_RETURN(message, ret, {}); 153e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 154e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 155e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko case TEST_OP_CHECK_CHANNEL_OBJECT: { 156e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::shared_ptr<TestChannel> channel; 157e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ChannelReference ref = 0; 158f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko if (!message.ReadAll(&ref, sizeof(ref))) 159f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko REPLY_ERROR_RETURN(message, EIO, {}); 160e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 161e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const Status<int> ret = 162e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko message.CheckChannel<TestChannel>(ref, &channel); 163e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!ret) 164f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko REPLY_MESSAGE_RETURN(message, ret, {}); 165e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 166e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (channel != nullptr) 167f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko REPLY_MESSAGE_RETURN(message, channel->channel_id(), {}); 168e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko else 169f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko REPLY_ERROR_RETURN(message, ENODATA, {}); 170e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 171e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 172e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko case TEST_OP_CHECK_CHANNEL_FROM_OTHER_SERVICE: { 173e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ChannelReference ref = 0; 174f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko if (!message.ReadAll(&ref, sizeof(ref))) 175f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko REPLY_ERROR_RETURN(message, EIO, {}); 176e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 177e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const Status<int> ret = message.CheckChannel<TestChannel>( 178e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko other_service_.get(), ref, nullptr); 179f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko REPLY_MESSAGE_RETURN(message, ret, {}); 180e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 181e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 182e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko case TEST_OP_GET_NEW_CHANNEL: { 183e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto channel = std::make_shared<TestChannel>(-1); 184e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Status<RemoteChannelHandle> channel_handle = 185e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko message.PushChannel(0, channel, &channel->channel_id_); 186f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko REPLY_MESSAGE_RETURN(message, channel_handle, {}); 187e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 188e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 189e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko case TEST_OP_GET_NEW_CHANNEL_FROM_OTHER_SERVICE: { 190e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (!other_service_) 191f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko REPLY_ERROR_RETURN(message, EINVAL, {}); 192e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 193e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto channel = std::make_shared<TestChannel>(-1); 194e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Status<RemoteChannelHandle> channel_handle = message.PushChannel( 195e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko other_service_.get(), 0, channel, &channel->channel_id_); 196f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko REPLY_MESSAGE_RETURN(message, channel_handle, {}); 197e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 198e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 199e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko case TEST_OP_GET_THIS_PROCESS_ID: 200f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko REPLY_MESSAGE_RETURN(message, message.GetProcessId(), {}); 201e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 202e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko case TEST_OP_GET_THIS_THREAD_ID: 203f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko REPLY_MESSAGE_RETURN(message, message.GetThreadId(), {}); 204e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 205e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko case TEST_OP_GET_THIS_EUID: 206f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko REPLY_MESSAGE_RETURN(message, message.GetEffectiveUserId(), {}); 207e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 208e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko case TEST_OP_GET_THIS_EGID: 209f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko REPLY_MESSAGE_RETURN(message, message.GetEffectiveGroupId(), {}); 210e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 211e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko case TEST_OP_POLLIN_FROM_SERVICE: 212e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko REPLY_MESSAGE_RETURN(message, message.ModifyChannelEvents(0, EPOLLIN), 213f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko {}); 214e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 215e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko case TEST_OP_SEND_LARGE_DATA_RETURN_SUM: { 216e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::array<int, kLargeDataSize> data_array; 217f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko size_t size_to_read = data_array.size() * sizeof(int); 218f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko if (!message.ReadAll(data_array.data(), size_to_read)) { 219f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko REPLY_ERROR_RETURN(message, EIO, {}); 220f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko } 221e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int sum = std::accumulate(data_array.begin(), data_array.end(), 0); 222f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko REPLY_MESSAGE_RETURN(message, sum, {}); 223e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 224e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 225e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko default: 226e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return Service::DefaultHandleMessage(message); 227e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 228e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 229e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 230e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const ImpulsePayload& GetImpulsePayload() const { return impulse_payload_; } 231e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 232e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko private: 233e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko friend BASE; 234e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 235e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::shared_ptr<TestChannel> test_channel_; 236e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::shared_ptr<TestService> other_service_; 237e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int service_id_; 238e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ImpulsePayload impulse_payload_; 239e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 240e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko static std::atomic<int> service_counter_; 241e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 242e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko TestService(const std::string& name, 243e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const std::shared_ptr<TestService>& other_service) 244e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko : TestService(name, other_service, false) {} 245e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 246e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko TestService(const std::string& name, 247e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const std::shared_ptr<TestService>& other_service, bool blocking) 248e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko : BASE(std::string("TestService") + name, 249f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko Endpoint::CreateAndBindSocket(kTestServicePath + name, blocking)), 250e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko other_service_(other_service), 251e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko service_id_(service_counter_++) {} 252e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 253e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko explicit TestService(const std::string& name) : TestService(name, nullptr) {} 254e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 255e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko TestService(const TestService&) = delete; 256e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko void operator=(const TestService&) = delete; 257e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}; 258e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 259e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkostd::atomic<int> TestService::service_counter_; 260e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 261e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Test client to send messages to the test service. 262e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoclass TestClient : public ClientBase<TestClient> { 263e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko public: 264e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Requests the service id of the service this channel is connected to. 265e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int GetServiceId() { 266e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Transaction trans{*this}; 267e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ReturnStatusOrError(trans.Send<int>(TEST_OP_GET_SERVICE_ID)); 268e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 269e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 270e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Requests the test channel to be set to this client's channel. 271e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int SetTestChannel() { 272e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Transaction trans{*this}; 273e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ReturnStatusOrError(trans.Send<int>(TEST_OP_SET_TEST_CHANNEL)); 274e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 275e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 276e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Request the test channel to be set to this client's channel using an async 277e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // message. 278e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int SetTestChannelAsync() { 279e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ReturnStatusOrError(SendImpulse(TEST_OP_SET_TEST_CHANNEL)); 280e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 281e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 282e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Sends a test async message with payload. 283e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int SendAsync(const void* buffer, size_t length) { 284e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Transaction trans{*this}; 285e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ReturnStatusOrError(SendImpulse(TEST_OP_IMPULSE, buffer, length)); 286e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 287e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 288e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Requests the channel id for this client. 289e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int GetThisChannelId() { 290e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Transaction trans{*this}; 291e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ReturnStatusOrError(trans.Send<int>(TEST_OP_GET_THIS_CHANNEL_ID)); 292e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 293e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 294e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Requests the channel id of the test channel. 295e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int GetTestChannelId() { 296e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Transaction trans{*this}; 297e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ReturnStatusOrError(trans.Send<int>(TEST_OP_GET_TEST_CHANNEL_ID)); 298e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 299e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 300e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Checks whether the fd |channel_id| is a channel to the test service. 301e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Returns the channel id of the channel. 302e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int CheckChannelIdArgument(BorrowedChannelHandle channel) { 303e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Transaction trans{*this}; 304f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko ChannelReference ref = trans.PushChannelHandle(channel).get(); 305e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ReturnStatusOrError(trans.Send<int>(TEST_OP_CHECK_CHANNEL_ID, &ref, 306e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko sizeof(ref), nullptr, 0)); 307e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 308e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 309e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Checks whether the fd |channel_id| is a channel to the test service. 310e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Returns the channel id of the channel exercising the context pointer. 311e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int CheckChannelObjectArgument(BorrowedChannelHandle channel) { 312e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Transaction trans{*this}; 313f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko ChannelReference ref = trans.PushChannelHandle(channel).get(); 314e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ReturnStatusOrError(trans.Send<int>(TEST_OP_CHECK_CHANNEL_OBJECT, 315e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko &ref, sizeof(ref), nullptr, 0)); 316e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 317e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 318e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Checks whether the fd |channel_fd| is a channel to the other test service. 319e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Returns 0 on success. 320e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int CheckChannelFromOtherService(BorrowedChannelHandle channel) { 321e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Transaction trans{*this}; 322f0a7bd033941e26e380232a0515e903cf8e678e5Alex Vakulenko ChannelReference ref = trans.PushChannelHandle(channel).get(); 323e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ReturnStatusOrError( 324e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko trans.Send<int>(TEST_OP_CHECK_CHANNEL_FROM_OTHER_SERVICE, &ref, 325e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko sizeof(ref), nullptr, 0)); 326e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 327e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 328e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Requests a new channel to the service. 329e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::unique_ptr<TestClient> GetNewChannel() { 330e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Transaction trans{*this}; 331e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto status = trans.Send<LocalChannelHandle>(TEST_OP_GET_NEW_CHANNEL); 332e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (status) 333e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return TestClient::Create(status.take()); 334e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko else 335e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return nullptr; 336e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 337e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 338e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Requests a new channel to the other service. 339e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::unique_ptr<TestClient> GetNewChannelFromOtherService() { 340e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Transaction trans{*this}; 341e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto status = trans.Send<LocalChannelHandle>( 342e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko TEST_OP_GET_NEW_CHANNEL_FROM_OTHER_SERVICE); 343e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (status) 344e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return TestClient::Create(status.take()); 345e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko else 346e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return nullptr; 347e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 348e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 349e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Requests an id from the message description. 350e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko pid_t GetThisProcessId() { 351e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Transaction trans{*this}; 352e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ReturnStatusOrError(trans.Send<int>(TEST_OP_GET_THIS_PROCESS_ID)); 353e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 354e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko pid_t GetThisThreadId() { 355e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Transaction trans{*this}; 356e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ReturnStatusOrError(trans.Send<int>(TEST_OP_GET_THIS_THREAD_ID)); 357e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 358e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko uid_t GetThisEffectiveUserId() { 359e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Transaction trans{*this}; 360e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ReturnStatusOrError(trans.Send<int>(TEST_OP_GET_THIS_EUID)); 361e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 362e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko gid_t GetThisEffectiveGroupId() { 363e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Transaction trans{*this}; 364e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ReturnStatusOrError(trans.Send<int>(TEST_OP_GET_THIS_EGID)); 365e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 366e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 367e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int SendPollHupEvent() { 368e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ReturnStatusOrError(SendImpulse(TEST_OP_POLLHUP_FROM_SERVICE)); 369e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 370e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 371e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int SendPollInEvent() { 372e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Transaction trans{*this}; 373e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ReturnStatusOrError(trans.Send<int>(TEST_OP_POLLIN_FROM_SERVICE)); 374e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 375e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 376e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int SendLargeDataReturnSum( 377e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const std::array<int, kLargeDataSize>& data_array) { 378e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko Transaction trans{*this}; 379e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko return ReturnStatusOrError( 380e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko trans.Send<int>(TEST_OP_SEND_LARGE_DATA_RETURN_SUM, data_array.data(), 381e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko data_array.size() * sizeof(int), nullptr, 0)); 382e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 383e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 384186d77217aaf769ff0a91753971e23bd249afca7Corey Tabaka Status<int> GetEventMask(int events) { 385186d77217aaf769ff0a91753971e23bd249afca7Corey Tabaka if (auto* client_channel = GetChannel()) { 386186d77217aaf769ff0a91753971e23bd249afca7Corey Tabaka return client_channel->GetEventMask(events); 387186d77217aaf769ff0a91753971e23bd249afca7Corey Tabaka } else { 388186d77217aaf769ff0a91753971e23bd249afca7Corey Tabaka return ErrorStatus(EINVAL); 389186d77217aaf769ff0a91753971e23bd249afca7Corey Tabaka } 390186d77217aaf769ff0a91753971e23bd249afca7Corey Tabaka } 391186d77217aaf769ff0a91753971e23bd249afca7Corey Tabaka 392e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko using ClientBase<TestClient>::event_fd; 393e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 394e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko enum : size_t { kMaxPayload = MAX_IMPULSE_LENGTH }; 395e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 396e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko private: 397e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko friend BASE; 398e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 399e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko explicit TestClient(const std::string& name) 400e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko : BASE{android::pdx::uds::ClientChannelFactory::Create(kTestServicePath + 401e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko name)} {} 402e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 403e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko explicit TestClient(LocalChannelHandle channel) 404e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko : BASE{android::pdx::uds::ClientChannel::Create(std::move(channel))} {} 405e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 406e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko TestClient(const TestClient&) = delete; 407e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko void operator=(const TestClient&) = delete; 408e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}; 409e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 410e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} // anonymous namespace 411e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 412e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Use a test fixture to ensure proper order of cleanup between clients, 413e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// services, and the dispatcher. These objects are cleaned up in the same 414e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// thread, order is important; either the service or the client must be 415e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// destroyed before the dispatcher is stopped. The reason for this is that 416e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// clients send blocking "close" messages to their respective services on 417e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// destruction. If this happens after the dispatcher is stopped the client 418e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// destructor will get blocked waiting for a reply that will never come. In 419e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// normal use of the service framework this is never an issue because clients 420e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// and the dispatcher for the same service are never destructed in the same 421e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// thread (they live in different processes). 422e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenkoclass ServiceFrameworkTest : public ::testing::Test { 423e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko protected: 424e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::unique_ptr<ServiceDispatcher> dispatcher_; 425e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::thread dispatch_thread_; 426e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 427e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko void SetUp() override { 428e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Create a dispatcher to handle messages to services. 4295a244ed36c8e45fd95b89ff916caf083fb182ec1Alex Vakulenko dispatcher_ = android::pdx::ServiceDispatcher::Create(); 430e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_NE(nullptr, dispatcher_); 431e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 432e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Start the message dispatch loop in a separate thread. 433e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko dispatch_thread_ = std::thread( 434e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::bind(&ServiceDispatcher::EnterDispatchLoop, dispatcher_.get())); 435e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 436e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 437e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko void TearDown() override { 438e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko if (dispatcher_) { 439e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Cancel the dispatcher and wait for the thread to terminate. Explicitly 440e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // join the thread so that destruction doesn't deallocate the dispatcher 441e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // before the thread finishes. 442e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko dispatcher_->SetCanceled(true); 443e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko dispatch_thread_.join(); 444e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 445e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko } 446e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko}; 447e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 448e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Test basic operation of TestService/TestClient classes. 449e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoTEST_F(ServiceFrameworkTest, BasicClientService) { 450e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Create a test service and add it to the dispatcher. 451e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto service = TestService::Create(kTestService1); 452e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_NE(nullptr, service); 453e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_EQ(0, dispatcher_->AddService(service)); 454e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 455e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Create a client to service. 456e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto client = TestClient::Create(kTestService1); 457e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_NE(nullptr, client); 458e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 459e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Get the channel id that will be returned by the next tests. 460e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const int channel_id = client->GetThisChannelId(); 461e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko EXPECT_LE(0, channel_id); 462e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 463e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Check return value before test channel is set. 464e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko EXPECT_EQ(-ENOENT, client->GetTestChannelId()); 465e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 466e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Set test channel and perform the test again. 467e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko EXPECT_EQ(0, client->SetTestChannel()); 468e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko EXPECT_EQ(channel_id, client->GetTestChannelId()); 469e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 470e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 471e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Test impulses. 472e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoTEST_F(ServiceFrameworkTest, Impulse) { 473e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Create a test service and add it to the dispatcher. 474e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto service = TestService::Create(kTestService1); 475e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_NE(nullptr, service); 476e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_EQ(0, dispatcher_->AddService(service)); 477e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 478e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto client = TestClient::Create(kTestService1); 479e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_NE(nullptr, client); 480e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 481e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Get the channel id that will be returned by the next tests. 482e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const int channel_id = client->GetThisChannelId(); 483e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko EXPECT_LE(0, channel_id); 484e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 485e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Check return value before test channel is set. 486e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko EXPECT_EQ(-ENOENT, client->GetTestChannelId()); 487e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 488e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Set test channel with an impulse and perform the test again. 489e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko EXPECT_EQ(0, client->SetTestChannelAsync()); 490e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko EXPECT_EQ(channel_id, client->GetTestChannelId()); 491e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 492e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ImpulsePayload expected_payload = {{'a', 'b', 'c'}}; 493e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko EXPECT_EQ(0, client->SendAsync(expected_payload.data(), 3)); 494e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Send a synchronous message to make sure the async message is handled before 495e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // we check the payload. 496e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko client->GetThisChannelId(); 497e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko EXPECT_EQ(expected_payload, service->GetImpulsePayload()); 498e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 499e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Impulse payloads are limited to 4 machine words. 500e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko EXPECT_EQ( 501e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 0, client->SendAsync(expected_payload.data(), TestClient::kMaxPayload)); 502e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko EXPECT_EQ(-EINVAL, client->SendAsync(expected_payload.data(), 503e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko TestClient::kMaxPayload + 1)); 504e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 505e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Test invalid pointer. 506e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const std::uint8_t* invalid_pointer = nullptr; 507e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko EXPECT_EQ(-EINVAL, client->SendAsync(invalid_pointer, sizeof(int))); 508e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 509e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 51052ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka// Test impulses. 51152ea25cf06cef250ec73052611b48556b3fce4d5Corey TabakaTEST_F(ServiceFrameworkTest, ImpulseHangup) { 51252ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka // Create a test service and add it to the dispatcher. 51352ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka auto service = TestService::Create(kTestService1); 51452ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka ASSERT_NE(nullptr, service); 51552ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka ASSERT_EQ(0, dispatcher_->AddService(service)); 51652ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka 51752ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka auto client = TestClient::Create(kTestService1); 51852ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka ASSERT_NE(nullptr, client); 51952ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka 52052ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka const int kMaxIterations = 1000; 52152ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka for (int i = 0; i < kMaxIterations; i++) { 52252ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka auto impulse_client = TestClient::Create(kTestService1); 52352ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka ASSERT_NE(nullptr, impulse_client); 52452ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka 52552ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka const uint8_t a = (i >> 0) & 0xff; 52652ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka const uint8_t b = (i >> 8) & 0xff; 52752ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka const uint8_t c = (i >> 16) & 0xff; 52852ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka const uint8_t d = (i >> 24) & 0xff; 52952ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka ImpulsePayload expected_payload = {{a, b, c, d}}; 53052ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka EXPECT_EQ(0, impulse_client->SendAsync(expected_payload.data(), 4)); 53152ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka 53252ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka // Hangup the impulse test client, then send a sync message over client to 53352ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka // make sure the hangup message is handled before checking the impulse 53452ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka // payload. 53552ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka impulse_client = nullptr; 53652ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka client->GetThisChannelId(); 53752ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka EXPECT_EQ(expected_payload, service->GetImpulsePayload()); 53852ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka } 53952ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka} 54052ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka 541e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Test Message::PushChannel/Service::PushChannel API. 542e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoTEST_F(ServiceFrameworkTest, PushChannel) { 543e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Create a test service and add it to the dispatcher. 544e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto other_service = TestService::Create(kTestService1); 545e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_NE(nullptr, other_service); 546e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_EQ(0, dispatcher_->AddService(other_service)); 547e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 548e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Create a second test service and add it to the dispatcher. 549e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto service = TestService::Create(kTestService2, other_service); 550e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_NE(nullptr, service); 551e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_EQ(0, dispatcher_->AddService(service)); 552e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 553e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Create a client to the second test service. 554e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto client1 = TestClient::Create(kTestService2); 555e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_NE(nullptr, client1); 556e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 557e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Test the creation of new channels using the push APIs. 558e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const int channel_id1 = client1->GetThisChannelId(); 559e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko EXPECT_LE(0, channel_id1); 560e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 561e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto client2 = client1->GetNewChannel(); 562e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko EXPECT_NE(nullptr, client2); 563e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko EXPECT_NE(client1->event_fd(), client2->event_fd()); 564e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 565e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const int channel_id2 = client2->GetThisChannelId(); 566e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko EXPECT_LE(0, channel_id2); 567e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko EXPECT_NE(channel_id1, channel_id2); 568e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 569e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto client3 = client1->GetNewChannelFromOtherService(); 570e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko EXPECT_NE(nullptr, client3); 571e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko EXPECT_NE(client1->event_fd(), client3->event_fd()); 572e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 573e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const int channel_id3 = client3->GetThisChannelId(); 574e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko EXPECT_LE(0, channel_id3); 575e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 576e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Test which services the channels are connected to. 577e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const int service_id1 = client1->GetServiceId(); 578e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko EXPECT_LE(0, service_id1); 579e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 580e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const int service_id2 = client2->GetServiceId(); 581e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko EXPECT_LE(0, service_id2); 582e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 583e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const int service_id3 = client3->GetServiceId(); 584e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko EXPECT_LE(0, service_id3); 585e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 586e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko EXPECT_EQ(service_id1, service_id2); 587e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko EXPECT_NE(service_id1, service_id3); 588e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 589e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 590e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// Tests process id, thread id, effective user id, and effective group id 591e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko// returned in the message description. 592e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoTEST_F(ServiceFrameworkTest, Ids) { 593e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Create a test service and add it to the dispatcher. 594e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto service = TestService::Create(kTestService1); 595e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_NE(nullptr, service); 596e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_EQ(0, dispatcher_->AddService(service)); 597e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 598e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Create a client to service. 599e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto client = TestClient::Create(kTestService1); 600e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_NE(nullptr, client); 601e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 602e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Pids 0-2 are defined, no user task should have them. 603e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 604e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const pid_t process_id1 = client->GetThisProcessId(); 605e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko EXPECT_LT(2, process_id1); 606e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 607e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko pid_t process_id2; 608e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 60952ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka std::thread thread([&]() { process_id2 = client->GetThisProcessId(); }); 610e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko thread.join(); 611e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 612e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko EXPECT_LT(2, process_id2); 613e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko EXPECT_EQ(process_id1, process_id2); 614e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 615e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // This test must run as root for the rest of these tests to work. 616e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const int euid1 = client->GetThisEffectiveUserId(); 617e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_EQ(0, euid1); 618e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 619e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const int egid1 = client->GetThisEffectiveGroupId(); 620e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko EXPECT_EQ(0, egid1); 621e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 622e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Set effective uid/gid to system. 623e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_EQ(0, setegid(AID_SYSTEM)); 624e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_EQ(0, seteuid(AID_SYSTEM)); 625e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 626e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const int euid2 = client->GetThisEffectiveUserId(); 627e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko EXPECT_EQ(AID_SYSTEM, euid2); 628e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 629e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko const int egid2 = client->GetThisEffectiveGroupId(); 630e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko EXPECT_EQ(AID_SYSTEM, egid2); 631e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 632e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Set the euid/egid back to root. 633e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_EQ(0, setegid(0)); 634e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_EQ(0, seteuid(0)); 635e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 636e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 637e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoTEST_F(ServiceFrameworkTest, PollIn) { 638e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Create a test service and add it to the dispatcher. 639e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto service = TestService::Create(kTestService1); 640e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_NE(nullptr, service); 641e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_EQ(0, dispatcher_->AddService(service)); 642e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 643e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Create a client to service. 644e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto client = TestClient::Create(kTestService1); 645e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_NE(nullptr, client); 646e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 64752ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka pollfd pfd{client->event_fd(), POLLIN, 0}; 64852ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka int count = poll(&pfd, 1, 0); 649e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_EQ(0, count); 650e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 651e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko client->SendPollInEvent(); 652e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 65352ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka count = poll(&pfd, 1, 10000 /*10s*/); 654e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_EQ(1, count); 65552ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka ASSERT_TRUE((POLLIN & pfd.revents) != 0); 656e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 657e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 658e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoTEST_F(ServiceFrameworkTest, PollHup) { 659e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Create a test service and add it to the dispatcher. 660e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto service = TestService::Create(kTestService1); 661e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_NE(nullptr, service); 662e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_EQ(0, dispatcher_->AddService(service)); 663e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 664e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Create a client to service. 665e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto client = TestClient::Create(kTestService1); 666e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_NE(nullptr, client); 667e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 66852ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka pollfd pfd{client->event_fd(), POLLIN, 0}; 66952ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka int count = poll(&pfd, 1, 0); 670e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_EQ(0, count); 671e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 672e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko client->SendPollHupEvent(); 673e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 67452ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka count = poll(&pfd, 1, 10000 /*10s*/); 675e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_EQ(1, count); 67652ea25cf06cef250ec73052611b48556b3fce4d5Corey Tabaka auto event_status = client->GetEventMask(pfd.revents); 677186d77217aaf769ff0a91753971e23bd249afca7Corey Tabaka ASSERT_TRUE(event_status.ok()); 678186d77217aaf769ff0a91753971e23bd249afca7Corey Tabaka ASSERT_TRUE((EPOLLHUP & event_status.get()) != 0); 679e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 680e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 681e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoTEST_F(ServiceFrameworkTest, LargeDataSum) { 682e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Create a test service and add it to the dispatcher. 683e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto service = TestService::Create(kTestService1); 684e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_NE(nullptr, service); 685e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_EQ(0, dispatcher_->AddService(service)); 686e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 687e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Create a client to service. 688e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto client = TestClient::Create(kTestService1); 689e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_NE(nullptr, client); 690e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 691e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::array<int, kLargeDataSize> data_array; 692e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko std::iota(data_array.begin(), data_array.end(), 0); 693e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int expected_sum = std::accumulate(data_array.begin(), data_array.end(), 0); 694e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko int sum = client->SendLargeDataReturnSum(data_array); 695e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_EQ(expected_sum, sum); 696e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 697e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 698e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex VakulenkoTEST_F(ServiceFrameworkTest, Cancel) { 699e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Create a test service and add it to the dispatcher. 700e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto service = TestService::Create(kTestService1, nullptr, true); 701e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_NE(nullptr, service); 702e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_EQ(0, dispatcher_->AddService(service)); 703e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 704e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Create a client to service. 705e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto client = TestClient::Create(kTestService1); 706e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_NE(nullptr, client); 707e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko 708e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto previous_time = std::chrono::system_clock::now(); 709e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko dispatcher_->ReceiveAndDispatch(100); // 0.1 seconds should block. 710e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko auto time = std::chrono::system_clock::now(); 711e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko ASSERT_LE(100, std::chrono::duration_cast<std::chrono::milliseconds>( 712e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko time - previous_time) 713e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko .count()); 714e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko service->Cancel(); 715e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko // Non-blocking. Return immediately. 716e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko dispatcher_->ReceiveAndDispatch(-1); 717e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko dispatcher_->ReceiveAndDispatch(-1); 718e4eec20f6263f4a42ae462456f60ea6c4518bb0aAlex Vakulenko} 719