You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
568 lines
20 KiB
568 lines
20 KiB
4 months ago
|
#include <pdx/client.h>
|
||
|
|
||
|
#include <gmock/gmock.h>
|
||
|
#include <sys/eventfd.h>
|
||
|
|
||
|
#include <pdx/mock_client_channel.h>
|
||
|
#include <pdx/mock_client_channel_factory.h>
|
||
|
#include <pdx/rpc/remote_method.h>
|
||
|
|
||
|
using android::pdx::BorrowedChannelHandle;
|
||
|
using android::pdx::BorrowedHandle;
|
||
|
using android::pdx::ClientBase;
|
||
|
using android::pdx::ClientChannel;
|
||
|
using android::pdx::ClientChannelFactory;
|
||
|
using android::pdx::ErrorStatus;
|
||
|
using android::pdx::LocalChannelHandle;
|
||
|
using android::pdx::LocalHandle;
|
||
|
using android::pdx::MockClientChannel;
|
||
|
using android::pdx::MockClientChannelFactory;
|
||
|
using android::pdx::RemoteChannelHandle;
|
||
|
using android::pdx::RemoteHandle;
|
||
|
using android::pdx::Status;
|
||
|
using android::pdx::Transaction;
|
||
|
using android::pdx::rpc::Void;
|
||
|
|
||
|
using testing::A;
|
||
|
using testing::AnyNumber;
|
||
|
using testing::ByMove;
|
||
|
using testing::Invoke;
|
||
|
using testing::Ne;
|
||
|
using testing::Return;
|
||
|
using testing::_;
|
||
|
|
||
|
namespace {
|
||
|
|
||
|
inline void* IntToPtr(intptr_t addr) { return reinterpret_cast<void*>(addr); }
|
||
|
inline const void* IntToConstPtr(intptr_t addr) {
|
||
|
return reinterpret_cast<const void*>(addr);
|
||
|
}
|
||
|
|
||
|
struct TestInterface final {
|
||
|
// Op codes.
|
||
|
enum {
|
||
|
kOpAdd = 0,
|
||
|
kOpSendFile,
|
||
|
kOpGetFile,
|
||
|
kOpPushChannel,
|
||
|
};
|
||
|
|
||
|
// Methods.
|
||
|
PDX_REMOTE_METHOD(Add, kOpAdd, int(int, int));
|
||
|
PDX_REMOTE_METHOD(SendFile, kOpSendFile, void(const LocalHandle& fd));
|
||
|
PDX_REMOTE_METHOD(GetFile, kOpGetFile, LocalHandle(const std::string&, int));
|
||
|
PDX_REMOTE_METHOD(PushChannel, kOpPushChannel, LocalChannelHandle(Void));
|
||
|
|
||
|
PDX_REMOTE_API(API, Add, SendFile, GetFile, PushChannel);
|
||
|
};
|
||
|
|
||
|
class SimpleClient : public ClientBase<SimpleClient> {
|
||
|
public:
|
||
|
explicit SimpleClient(std::unique_ptr<ClientChannel> channel)
|
||
|
: BASE{std::move(channel)} {}
|
||
|
SimpleClient(std::unique_ptr<ClientChannelFactory> channel_factory,
|
||
|
int64_t timeout_ms)
|
||
|
: BASE{std::move(channel_factory), timeout_ms} {
|
||
|
EnableAutoReconnect(timeout_ms);
|
||
|
}
|
||
|
|
||
|
using BASE::SendImpulse;
|
||
|
using BASE::InvokeRemoteMethod;
|
||
|
using BASE::InvokeRemoteMethodInPlace;
|
||
|
using BASE::Close;
|
||
|
using BASE::IsConnected;
|
||
|
using BASE::EnableAutoReconnect;
|
||
|
using BASE::DisableAutoReconnect;
|
||
|
using BASE::event_fd;
|
||
|
using BASE::GetChannel;
|
||
|
|
||
|
MOCK_METHOD0(OnConnect, void());
|
||
|
};
|
||
|
|
||
|
class FailingClient : public ClientBase<FailingClient> {
|
||
|
public:
|
||
|
explicit FailingClient(std::unique_ptr<ClientChannel> channel, int error_code)
|
||
|
: BASE{std::move(channel)} {
|
||
|
Close(error_code);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
class ClientChannelTest : public testing::Test {
|
||
|
public:
|
||
|
ClientChannelTest()
|
||
|
: client_{SimpleClient::Create(
|
||
|
std::make_unique<testing::StrictMock<MockClientChannel>>())} {}
|
||
|
|
||
|
MockClientChannel* mock_channel() {
|
||
|
return static_cast<MockClientChannel*>(client_->GetChannel());
|
||
|
}
|
||
|
|
||
|
std::unique_ptr<SimpleClient> client_;
|
||
|
};
|
||
|
|
||
|
class ClientChannelFactoryTest : public testing::Test {
|
||
|
public:
|
||
|
ClientChannelFactoryTest() {
|
||
|
auto factory =
|
||
|
std::make_unique<testing::NiceMock<MockClientChannelFactory>>();
|
||
|
ON_CALL(*factory, Connect(kTimeout))
|
||
|
.WillByDefault(Invoke(this, &ClientChannelFactoryTest::OnConnect));
|
||
|
client_ = SimpleClient::Create(std::move(factory), kTimeout);
|
||
|
}
|
||
|
|
||
|
MockClientChannel* mock_channel() {
|
||
|
return static_cast<MockClientChannel*>(client_->GetChannel());
|
||
|
}
|
||
|
|
||
|
Status<std::unique_ptr<ClientChannel>> OnConnect(int64_t /*timeout_ms*/) {
|
||
|
if (on_connect_error_)
|
||
|
return ErrorStatus(on_connect_error_);
|
||
|
std::unique_ptr<MockClientChannel> channel =
|
||
|
std::make_unique<testing::StrictMock<MockClientChannel>>();
|
||
|
if (on_connect_callback_)
|
||
|
on_connect_callback_(channel.get());
|
||
|
return Status<std::unique_ptr<ClientChannel>>{std::move(channel)};
|
||
|
}
|
||
|
|
||
|
void OnConnectCallback(std::function<void(MockClientChannel*)> callback) {
|
||
|
on_connect_callback_ = callback;
|
||
|
}
|
||
|
void SetOnConnectError(int error) { on_connect_error_ = error; }
|
||
|
void ResetOnConnectError() { on_connect_error_ = 0; }
|
||
|
|
||
|
constexpr static int64_t kTimeout = 123;
|
||
|
std::unique_ptr<SimpleClient> client_;
|
||
|
std::function<void(MockClientChannel*)> on_connect_callback_;
|
||
|
int on_connect_error_{0};
|
||
|
};
|
||
|
|
||
|
constexpr int64_t ClientChannelFactoryTest::kTimeout;
|
||
|
|
||
|
class ClientTransactionTest : public ClientChannelTest {
|
||
|
public:
|
||
|
ClientTransactionTest() : transaction_{*client_} {}
|
||
|
|
||
|
Transaction transaction_;
|
||
|
};
|
||
|
|
||
|
} // anonymous namespace
|
||
|
|
||
|
TEST_F(ClientChannelTest, IsInitialized) {
|
||
|
ASSERT_NE(client_.get(), nullptr);
|
||
|
EXPECT_TRUE(client_->IsInitialized());
|
||
|
EXPECT_TRUE(client_->IsConnected());
|
||
|
}
|
||
|
|
||
|
TEST_F(ClientChannelTest, CloseOnConstruction) {
|
||
|
FailingClient failed_client1{std::make_unique<MockClientChannel>(), EACCES};
|
||
|
ASSERT_FALSE(failed_client1.IsInitialized());
|
||
|
EXPECT_EQ(-EACCES, failed_client1.error());
|
||
|
|
||
|
FailingClient failed_client2{std::make_unique<MockClientChannel>(), -EACCES};
|
||
|
ASSERT_FALSE(failed_client2.IsInitialized());
|
||
|
EXPECT_EQ(-EACCES, failed_client2.error());
|
||
|
|
||
|
auto failed_client3 =
|
||
|
FailingClient::Create(std::make_unique<MockClientChannel>(), EIO);
|
||
|
ASSERT_EQ(failed_client3.get(), nullptr);
|
||
|
}
|
||
|
|
||
|
TEST_F(ClientChannelTest, IsConnected) {
|
||
|
EXPECT_TRUE(client_->IsConnected());
|
||
|
EXPECT_EQ(0, client_->error());
|
||
|
client_->Close(-EINVAL);
|
||
|
EXPECT_FALSE(client_->IsConnected());
|
||
|
EXPECT_EQ(-EINVAL, client_->error());
|
||
|
}
|
||
|
|
||
|
TEST_F(ClientChannelTest, event_fd) {
|
||
|
EXPECT_CALL(*mock_channel(), event_fd()).WillOnce(Return(12));
|
||
|
EXPECT_EQ(12, client_->event_fd());
|
||
|
}
|
||
|
|
||
|
TEST_F(ClientChannelTest, SendImpulse) {
|
||
|
EXPECT_CALL(*mock_channel(), SendImpulse(123, nullptr, 0))
|
||
|
.WillOnce(Return(Status<void>{}));
|
||
|
EXPECT_TRUE(client_->SendImpulse(123));
|
||
|
|
||
|
EXPECT_CALL(*mock_channel(), SendImpulse(17, nullptr, 0))
|
||
|
.WillOnce(Return(ErrorStatus{EIO}));
|
||
|
auto status = client_->SendImpulse(17);
|
||
|
ASSERT_FALSE(status);
|
||
|
EXPECT_EQ(EIO, status.error());
|
||
|
|
||
|
const void* const kTestPtr = IntToConstPtr(1234);
|
||
|
EXPECT_CALL(*mock_channel(), SendImpulse(1, kTestPtr, 17))
|
||
|
.WillOnce(Return(Status<void>{}));
|
||
|
EXPECT_TRUE(client_->SendImpulse(1, kTestPtr, 17));
|
||
|
}
|
||
|
|
||
|
TEST_F(ClientChannelTest, InvokeRemoteMethodNullTransactionState) {
|
||
|
EXPECT_CALL(*mock_channel(), AllocateTransactionState())
|
||
|
.WillOnce(Return(nullptr));
|
||
|
EXPECT_CALL(*mock_channel(),
|
||
|
SendWithInt(nullptr, TestInterface::kOpAdd, _, _, nullptr, 0))
|
||
|
.WillOnce(Return(9));
|
||
|
EXPECT_CALL(*mock_channel(), FreeTransactionState(nullptr));
|
||
|
EXPECT_TRUE(client_->InvokeRemoteMethod<TestInterface::Add>(4, 5));
|
||
|
}
|
||
|
|
||
|
TEST_F(ClientChannelTest, InvokeRemoteMethodAddSuccess) {
|
||
|
void* const kTransactionState = IntToPtr(123);
|
||
|
EXPECT_CALL(*mock_channel(), AllocateTransactionState())
|
||
|
.WillOnce(Return(kTransactionState));
|
||
|
EXPECT_CALL(
|
||
|
*mock_channel(),
|
||
|
SendWithInt(kTransactionState, TestInterface::kOpAdd, _, _, nullptr, 0))
|
||
|
.WillOnce(Return(3));
|
||
|
EXPECT_CALL(*mock_channel(), FreeTransactionState(kTransactionState));
|
||
|
Status<int> status = client_->InvokeRemoteMethod<TestInterface::Add>(1, 2);
|
||
|
ASSERT_TRUE(status);
|
||
|
EXPECT_EQ(3, status.get());
|
||
|
}
|
||
|
|
||
|
TEST_F(ClientChannelTest, InvokeRemoteMethodAddFailure) {
|
||
|
void* const kTransactionState = IntToPtr(123);
|
||
|
EXPECT_CALL(*mock_channel(), AllocateTransactionState())
|
||
|
.WillOnce(Return(kTransactionState));
|
||
|
EXPECT_CALL(
|
||
|
*mock_channel(),
|
||
|
SendWithInt(kTransactionState, TestInterface::kOpAdd, _, _, nullptr, 0))
|
||
|
.WillOnce(Return(ErrorStatus{EIO}));
|
||
|
EXPECT_CALL(*mock_channel(), FreeTransactionState(kTransactionState));
|
||
|
Status<int> status = client_->InvokeRemoteMethod<TestInterface::Add>(1, 2);
|
||
|
ASSERT_FALSE(status);
|
||
|
EXPECT_EQ(EIO, status.error());
|
||
|
}
|
||
|
|
||
|
TEST_F(ClientChannelTest, InvokeRemoteMethodGetFileSuccess) {
|
||
|
void* const kTransactionState = IntToPtr(123);
|
||
|
int fd = eventfd(0, 0);
|
||
|
EXPECT_CALL(*mock_channel(), AllocateTransactionState())
|
||
|
.WillOnce(Return(kTransactionState));
|
||
|
EXPECT_CALL(*mock_channel(),
|
||
|
SendWithFileHandle(kTransactionState, TestInterface::kOpGetFile,
|
||
|
_, _, nullptr, 0))
|
||
|
.WillOnce(Return(ByMove(LocalHandle{fd})));
|
||
|
EXPECT_CALL(*mock_channel(), FreeTransactionState(kTransactionState));
|
||
|
Status<LocalHandle> status =
|
||
|
client_->InvokeRemoteMethod<TestInterface::GetFile>();
|
||
|
ASSERT_TRUE(status);
|
||
|
EXPECT_EQ(fd, status.get().Get());
|
||
|
}
|
||
|
|
||
|
TEST_F(ClientChannelTest, InvokeRemoteMethodGetFileFailure) {
|
||
|
void* const kTransactionState = IntToPtr(123);
|
||
|
EXPECT_CALL(*mock_channel(), AllocateTransactionState())
|
||
|
.WillOnce(Return(kTransactionState));
|
||
|
EXPECT_CALL(*mock_channel(),
|
||
|
SendWithFileHandle(kTransactionState, TestInterface::kOpGetFile,
|
||
|
_, _, nullptr, 0))
|
||
|
.WillOnce(Return(ByMove(ErrorStatus{EACCES})));
|
||
|
EXPECT_CALL(*mock_channel(), FreeTransactionState(kTransactionState));
|
||
|
Status<LocalHandle> status =
|
||
|
client_->InvokeRemoteMethod<TestInterface::GetFile>("file", 0);
|
||
|
ASSERT_FALSE(status);
|
||
|
EXPECT_EQ(EACCES, status.error());
|
||
|
}
|
||
|
|
||
|
TEST_F(ClientChannelTest, InvokeRemoteMethodPushChannelSuccess) {
|
||
|
void* const kTransactionState = IntToPtr(123);
|
||
|
const int32_t kHandleValue = 17;
|
||
|
EXPECT_CALL(*mock_channel(), AllocateTransactionState())
|
||
|
.WillOnce(Return(kTransactionState));
|
||
|
EXPECT_CALL(
|
||
|
*mock_channel(),
|
||
|
SendWithChannelHandle(kTransactionState, TestInterface::kOpPushChannel, _,
|
||
|
_, nullptr, 0))
|
||
|
.WillOnce(Return(ByMove(LocalChannelHandle{nullptr, kHandleValue})));
|
||
|
EXPECT_CALL(*mock_channel(), FreeTransactionState(kTransactionState));
|
||
|
Status<LocalChannelHandle> status =
|
||
|
client_->InvokeRemoteMethod<TestInterface::PushChannel>();
|
||
|
ASSERT_TRUE(status);
|
||
|
EXPECT_EQ(kHandleValue, status.get().value());
|
||
|
}
|
||
|
|
||
|
TEST_F(ClientChannelTest, InvokeRemoteMethodPushChannelFailure) {
|
||
|
void* const kTransactionState = IntToPtr(123);
|
||
|
EXPECT_CALL(*mock_channel(), AllocateTransactionState())
|
||
|
.WillOnce(Return(kTransactionState));
|
||
|
EXPECT_CALL(
|
||
|
*mock_channel(),
|
||
|
SendWithChannelHandle(kTransactionState, TestInterface::kOpPushChannel, _,
|
||
|
_, nullptr, 0))
|
||
|
.WillOnce(Return(ByMove(ErrorStatus{EACCES})));
|
||
|
EXPECT_CALL(*mock_channel(), FreeTransactionState(kTransactionState));
|
||
|
Status<LocalChannelHandle> status =
|
||
|
client_->InvokeRemoteMethod<TestInterface::PushChannel>();
|
||
|
ASSERT_FALSE(status);
|
||
|
EXPECT_EQ(EACCES, status.error());
|
||
|
}
|
||
|
|
||
|
TEST_F(ClientChannelTest, InvokeRemoteMethodSendFileSuccess) {
|
||
|
void* const kTransactionState = IntToPtr(123);
|
||
|
LocalHandle fd{eventfd(0, 0)};
|
||
|
EXPECT_CALL(*mock_channel(), AllocateTransactionState())
|
||
|
.WillOnce(Return(kTransactionState));
|
||
|
EXPECT_CALL(*mock_channel(),
|
||
|
PushFileHandle(kTransactionState, A<const LocalHandle&>()))
|
||
|
.WillOnce(Return(1));
|
||
|
EXPECT_CALL(*mock_channel(),
|
||
|
SendWithInt(kTransactionState, TestInterface::kOpSendFile, _, _,
|
||
|
nullptr, 0))
|
||
|
.WillOnce(Return(0));
|
||
|
EXPECT_CALL(*mock_channel(), FreeTransactionState(kTransactionState));
|
||
|
EXPECT_TRUE(client_->InvokeRemoteMethod<TestInterface::SendFile>(fd));
|
||
|
}
|
||
|
|
||
|
TEST_F(ClientChannelTest, InvokeRemoteMethodSendFileFailure) {
|
||
|
void* const kTransactionState = IntToPtr(123);
|
||
|
LocalHandle fd{eventfd(0, 0)};
|
||
|
EXPECT_CALL(*mock_channel(), AllocateTransactionState())
|
||
|
.WillOnce(Return(kTransactionState));
|
||
|
EXPECT_CALL(*mock_channel(),
|
||
|
PushFileHandle(kTransactionState, A<const LocalHandle&>()))
|
||
|
.WillOnce(Return(1));
|
||
|
EXPECT_CALL(*mock_channel(),
|
||
|
SendWithInt(kTransactionState, TestInterface::kOpSendFile, _, _,
|
||
|
nullptr, 0))
|
||
|
.WillOnce(Return(ErrorStatus{EACCES}));
|
||
|
EXPECT_CALL(*mock_channel(), FreeTransactionState(kTransactionState));
|
||
|
EXPECT_FALSE(client_->InvokeRemoteMethod<TestInterface::SendFile>(fd));
|
||
|
}
|
||
|
|
||
|
TEST_F(ClientChannelFactoryTest, IsInitialized) {
|
||
|
ASSERT_NE(client_.get(), nullptr);
|
||
|
EXPECT_TRUE(client_->IsInitialized());
|
||
|
EXPECT_TRUE(client_->IsConnected());
|
||
|
}
|
||
|
|
||
|
TEST_F(ClientChannelFactoryTest, NotConnectedButInitialized) {
|
||
|
auto factory =
|
||
|
std::make_unique<testing::NiceMock<MockClientChannelFactory>>();
|
||
|
EXPECT_CALL(*factory, Connect(kTimeout))
|
||
|
.WillOnce(Return(ByMove(ErrorStatus(ESHUTDOWN))))
|
||
|
.WillOnce(Invoke(this, &ClientChannelFactoryTest::OnConnect));
|
||
|
client_ = SimpleClient::Create(std::move(factory), kTimeout);
|
||
|
ASSERT_NE(client_.get(), nullptr);
|
||
|
EXPECT_TRUE(client_->IsInitialized());
|
||
|
EXPECT_FALSE(client_->IsConnected());
|
||
|
client_->DisableAutoReconnect();
|
||
|
ASSERT_FALSE(client_->SendImpulse(17));
|
||
|
EXPECT_FALSE(client_->IsConnected());
|
||
|
client_->EnableAutoReconnect(kTimeout);
|
||
|
EXPECT_CALL(*client_, OnConnect());
|
||
|
OnConnectCallback([](auto* mock) {
|
||
|
EXPECT_CALL(*mock, SendImpulse(17, nullptr, 0))
|
||
|
.WillOnce(Return(Status<void>{}));
|
||
|
});
|
||
|
ASSERT_TRUE(client_->SendImpulse(17));
|
||
|
EXPECT_TRUE(client_->IsConnected());
|
||
|
}
|
||
|
|
||
|
TEST_F(ClientChannelFactoryTest, CheckDisconnect) {
|
||
|
EXPECT_CALL(*mock_channel(), SendImpulse(17, nullptr, 0))
|
||
|
.WillOnce(Return(ErrorStatus{ESHUTDOWN}));
|
||
|
ASSERT_FALSE(client_->SendImpulse(17));
|
||
|
EXPECT_FALSE(client_->IsConnected());
|
||
|
EXPECT_EQ(-ESHUTDOWN, client_->error());
|
||
|
}
|
||
|
|
||
|
TEST_F(ClientChannelFactoryTest, CheckReconnect) {
|
||
|
client_->Close(ESHUTDOWN);
|
||
|
ASSERT_FALSE(client_->IsConnected());
|
||
|
|
||
|
EXPECT_CALL(*client_, OnConnect());
|
||
|
OnConnectCallback([](auto* mock) {
|
||
|
EXPECT_CALL(*mock, SendImpulse(17, nullptr, 0))
|
||
|
.WillOnce(Return(Status<void>{}));
|
||
|
});
|
||
|
ASSERT_TRUE(client_->SendImpulse(17));
|
||
|
EXPECT_TRUE(client_->IsConnected());
|
||
|
}
|
||
|
|
||
|
TEST_F(ClientChannelFactoryTest, CloseOnConnect) {
|
||
|
client_->Close(ESHUTDOWN);
|
||
|
|
||
|
EXPECT_CALL(*client_, OnConnect()).WillOnce(Invoke([this] {
|
||
|
client_->Close(EIO);
|
||
|
}));
|
||
|
auto status = client_->SendImpulse(17);
|
||
|
ASSERT_FALSE(status);
|
||
|
EXPECT_EQ(EIO, status.error());
|
||
|
EXPECT_FALSE(client_->IsConnected());
|
||
|
EXPECT_EQ(-EIO, client_->error());
|
||
|
}
|
||
|
|
||
|
TEST_F(ClientChannelFactoryTest, DisableAutoReconnect) {
|
||
|
client_->Close(EIO);
|
||
|
ASSERT_FALSE(client_->IsConnected());
|
||
|
client_->DisableAutoReconnect();
|
||
|
auto status = client_->SendImpulse(17);
|
||
|
ASSERT_FALSE(status);
|
||
|
EXPECT_EQ(ESHUTDOWN, status.error());
|
||
|
EXPECT_FALSE(client_->IsConnected());
|
||
|
client_->EnableAutoReconnect(kTimeout);
|
||
|
EXPECT_CALL(*client_, OnConnect());
|
||
|
OnConnectCallback([](auto* mock) {
|
||
|
EXPECT_CALL(*mock, SendImpulse(17, nullptr, 0))
|
||
|
.WillOnce(Return(Status<void>{}));
|
||
|
});
|
||
|
ASSERT_TRUE(client_->SendImpulse(17));
|
||
|
EXPECT_TRUE(client_->IsConnected());
|
||
|
}
|
||
|
|
||
|
TEST_F(ClientTransactionTest, SendNoData) {
|
||
|
void* const kTransactionState = IntToPtr(123);
|
||
|
EXPECT_CALL(*mock_channel(), AllocateTransactionState())
|
||
|
.WillOnce(Return(kTransactionState));
|
||
|
EXPECT_CALL(*mock_channel(), FreeTransactionState(kTransactionState));
|
||
|
EXPECT_CALL(*mock_channel(),
|
||
|
SendWithInt(kTransactionState, 1, nullptr, 0, nullptr, 0))
|
||
|
.WillOnce(Return(0));
|
||
|
EXPECT_TRUE(transaction_.Send<void>(1));
|
||
|
EXPECT_CALL(*mock_channel(),
|
||
|
SendWithFileHandle(kTransactionState, 2, nullptr, 0, nullptr, 0))
|
||
|
.WillOnce(Return(ByMove(LocalHandle{-1})));
|
||
|
EXPECT_TRUE(transaction_.Send<LocalHandle>(2));
|
||
|
EXPECT_CALL(*mock_channel(), SendWithChannelHandle(kTransactionState, 3,
|
||
|
nullptr, 0, nullptr, 0))
|
||
|
.WillOnce(Return(ByMove(LocalChannelHandle{nullptr, 1})));
|
||
|
EXPECT_TRUE(transaction_.Send<LocalChannelHandle>(3));
|
||
|
}
|
||
|
|
||
|
TEST_F(ClientTransactionTest, SendNoState) {
|
||
|
EXPECT_CALL(*mock_channel(), AllocateTransactionState())
|
||
|
.WillOnce(Return(nullptr));
|
||
|
EXPECT_CALL(*mock_channel(), SendWithInt(nullptr, 1, nullptr, 0, nullptr, 0))
|
||
|
.WillOnce(Return(0));
|
||
|
EXPECT_CALL(*mock_channel(), FreeTransactionState(nullptr));
|
||
|
EXPECT_TRUE(transaction_.Send<void>(1));
|
||
|
}
|
||
|
|
||
|
TEST_F(ClientTransactionTest, SendBuffers) {
|
||
|
const void* const kSendBuffer = IntToConstPtr(123);
|
||
|
const size_t kSendSize = 12;
|
||
|
void* const kReceiveBuffer = IntToPtr(456);
|
||
|
const size_t kReceiveSize = 34;
|
||
|
|
||
|
EXPECT_CALL(*mock_channel(), AllocateTransactionState())
|
||
|
.WillOnce(Return(nullptr));
|
||
|
EXPECT_CALL(*mock_channel(), FreeTransactionState(nullptr));
|
||
|
|
||
|
EXPECT_CALL(*mock_channel(), SendWithInt(nullptr, 1, nullptr, 0, nullptr, 0))
|
||
|
.WillOnce(Return(0));
|
||
|
EXPECT_TRUE(transaction_.Send<void>(1, nullptr, 0, nullptr, 0));
|
||
|
|
||
|
EXPECT_CALL(*mock_channel(),
|
||
|
SendWithInt(nullptr, 2, Ne(nullptr), 1, nullptr, 0))
|
||
|
.WillOnce(Return(0));
|
||
|
EXPECT_TRUE(transaction_.Send<void>(2, kSendBuffer, kSendSize, nullptr, 0));
|
||
|
|
||
|
EXPECT_CALL(*mock_channel(), SendWithInt(nullptr, 3, nullptr, 0, nullptr, 0))
|
||
|
.WillOnce(Return(0));
|
||
|
EXPECT_TRUE(transaction_.Send<void>(3, kSendBuffer, 0, nullptr, 0));
|
||
|
|
||
|
EXPECT_CALL(*mock_channel(),
|
||
|
SendWithInt(nullptr, 4, nullptr, 0, Ne(nullptr), 1))
|
||
|
.WillOnce(Return(0));
|
||
|
EXPECT_TRUE(
|
||
|
transaction_.Send<void>(4, nullptr, 0, kReceiveBuffer, kReceiveSize));
|
||
|
|
||
|
EXPECT_CALL(*mock_channel(), SendWithInt(nullptr, 5, nullptr, 0, nullptr, 0))
|
||
|
.WillOnce(Return(0));
|
||
|
EXPECT_TRUE(transaction_.Send<void>(5, nullptr, 0, kReceiveBuffer, 0));
|
||
|
|
||
|
EXPECT_CALL(*mock_channel(),
|
||
|
SendWithInt(nullptr, 5, Ne(nullptr), 1, Ne(nullptr), 1))
|
||
|
.WillOnce(Return(0));
|
||
|
EXPECT_TRUE(transaction_.Send<void>(5, kSendBuffer, kSendSize, kReceiveBuffer,
|
||
|
kReceiveSize));
|
||
|
}
|
||
|
|
||
|
TEST_F(ClientTransactionTest, SendVector) {
|
||
|
iovec send[3] = {};
|
||
|
iovec recv[4] = {};
|
||
|
|
||
|
EXPECT_CALL(*mock_channel(), AllocateTransactionState())
|
||
|
.WillOnce(Return(nullptr));
|
||
|
EXPECT_CALL(*mock_channel(), FreeTransactionState(nullptr));
|
||
|
|
||
|
EXPECT_CALL(*mock_channel(), SendWithInt(nullptr, 1, nullptr, 0, nullptr, 0))
|
||
|
.WillOnce(Return(0));
|
||
|
EXPECT_TRUE(transaction_.SendVector<void>(1, nullptr, 0, nullptr, 0));
|
||
|
|
||
|
EXPECT_CALL(*mock_channel(), SendWithInt(nullptr, 2, send, 3, recv, 4))
|
||
|
.WillOnce(Return(0));
|
||
|
EXPECT_TRUE(transaction_.SendVector<void>(2, send, 3, recv, 4));
|
||
|
|
||
|
EXPECT_CALL(*mock_channel(), SendWithInt(nullptr, 3, send, 3, nullptr, 0))
|
||
|
.WillOnce(Return(0));
|
||
|
EXPECT_TRUE(transaction_.SendVector<void>(3, send, nullptr));
|
||
|
|
||
|
EXPECT_CALL(*mock_channel(), SendWithInt(nullptr, 4, nullptr, 0, recv, 4))
|
||
|
.WillOnce(Return(0));
|
||
|
EXPECT_TRUE(transaction_.SendVector<void>(4, nullptr, recv));
|
||
|
|
||
|
EXPECT_CALL(*mock_channel(), SendWithInt(nullptr, 5, send, 3, recv, 4))
|
||
|
.WillOnce(Return(0));
|
||
|
EXPECT_TRUE(transaction_.SendVector<void>(5, send, recv));
|
||
|
}
|
||
|
|
||
|
TEST_F(ClientTransactionTest, PushHandle) {
|
||
|
void* const kTransactionState = IntToPtr(123);
|
||
|
EXPECT_CALL(*mock_channel(), AllocateTransactionState())
|
||
|
.WillOnce(Return(kTransactionState));
|
||
|
EXPECT_CALL(*mock_channel(), FreeTransactionState(kTransactionState));
|
||
|
|
||
|
EXPECT_CALL(*mock_channel(),
|
||
|
PushFileHandle(kTransactionState, A<const LocalHandle&>()))
|
||
|
.WillOnce(Return(1));
|
||
|
EXPECT_EQ(1, transaction_.PushFileHandle(LocalHandle{-1}).get());
|
||
|
|
||
|
EXPECT_CALL(*mock_channel(),
|
||
|
PushFileHandle(kTransactionState, A<const BorrowedHandle&>()))
|
||
|
.WillOnce(Return(2));
|
||
|
EXPECT_EQ(2, transaction_.PushFileHandle(BorrowedHandle{-1}).get());
|
||
|
|
||
|
EXPECT_EQ(3, transaction_.PushFileHandle(RemoteHandle{3}).get());
|
||
|
|
||
|
EXPECT_CALL(
|
||
|
*mock_channel(),
|
||
|
PushChannelHandle(kTransactionState, A<const LocalChannelHandle&>()))
|
||
|
.WillOnce(Return(11));
|
||
|
EXPECT_EQ(
|
||
|
11, transaction_.PushChannelHandle(LocalChannelHandle{nullptr, 1}).get());
|
||
|
|
||
|
EXPECT_CALL(
|
||
|
*mock_channel(),
|
||
|
PushChannelHandle(kTransactionState, A<const BorrowedChannelHandle&>()))
|
||
|
.WillOnce(Return(12));
|
||
|
EXPECT_EQ(12, transaction_.PushChannelHandle(BorrowedChannelHandle{2}).get());
|
||
|
|
||
|
EXPECT_EQ(13, transaction_.PushChannelHandle(RemoteChannelHandle{13}).get());
|
||
|
}
|
||
|
|
||
|
TEST_F(ClientTransactionTest, GetHandle) {
|
||
|
void* const kTransactionState = IntToPtr(123);
|
||
|
EXPECT_CALL(*mock_channel(), AllocateTransactionState())
|
||
|
.WillOnce(Return(kTransactionState));
|
||
|
EXPECT_CALL(*mock_channel(), FreeTransactionState(kTransactionState));
|
||
|
|
||
|
EXPECT_CALL(*mock_channel(), GetFileHandle(kTransactionState, 1, _))
|
||
|
.WillOnce(Return(false))
|
||
|
.WillOnce(Return(true));
|
||
|
|
||
|
LocalHandle file_handle;
|
||
|
EXPECT_FALSE(transaction_.GetFileHandle(1, &file_handle));
|
||
|
EXPECT_TRUE(transaction_.GetFileHandle(1, &file_handle));
|
||
|
|
||
|
EXPECT_CALL(*mock_channel(), GetChannelHandle(kTransactionState, 2, _))
|
||
|
.WillOnce(Return(false))
|
||
|
.WillOnce(Return(true));
|
||
|
|
||
|
LocalChannelHandle channel_handle;
|
||
|
EXPECT_FALSE(transaction_.GetChannelHandle(2, &channel_handle));
|
||
|
EXPECT_TRUE(transaction_.GetChannelHandle(2, &channel_handle));
|
||
|
}
|