#ifdef UNSAFE_BUFFERS_BUILD
#pragma allow_unsafe_libc_calls
#endif
#include "mojo/core/node_channel.h"
#include "base/functional/callback_helpers.h"
#include "base/logging.h"
#include "base/memory/scoped_refptr.h"
#include "base/message_loop/message_pump_type.h"
#include "base/test/task_environment.h"
#include "base/threading/thread.h"
#include "mojo/core/embedder/embedder.h"
#include "mojo/core/test/mock_node_channel_delegate.h"
#include "mojo/public/cpp/platform/platform_channel.h"
#include "mojo/public/cpp/platform/platform_channel_endpoint.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace mojo {
namespace core {
namespace {
using ports::NodeName;
using testing::_;
class NodeChannelTest : public testing::Test {
public:
void SetUp() override {
if (IsMojoIpczEnabled()) {
GTEST_SKIP() << "NodeChannel is never used when ipcz is enabled, so "
<< "these tests are neither supported nor relevant.";
}
}
MockNodeChannelDelegate local_delegate_;
MockNodeChannelDelegate remote_delegate_;
};
scoped_refptr<NodeChannel> CreateNodeChannel(NodeChannel::Delegate* delegate,
PlatformChannelEndpoint endpoint) {
return NodeChannel::Create(delegate, ConnectionParams(std::move(endpoint)),
Channel::HandlePolicy::kAcceptHandles,
GetIOTaskRunner(), base::NullCallback());
}
TEST_F(NodeChannelTest, DestructionIsSafe) {
base::test::TaskEnvironment task_environment;
PlatformChannel channel;
auto local_channel =
CreateNodeChannel(&local_delegate_, channel.TakeLocalEndpoint());
local_channel->Start();
auto remote_channel =
CreateNodeChannel(&remote_delegate_, channel.TakeRemoteEndpoint());
remote_channel->Start();
const NodeName kRemoteNodeName{123, 456};
const NodeName kToken{987, 654};
base::RunLoop loop;
EXPECT_CALL(local_delegate_,
OnAcceptInvitee(ports::kInvalidNodeName, kRemoteNodeName, kToken))
.WillRepeatedly([&] { loop.Quit(); });
remote_channel->AcceptInvitee(kRemoteNodeName, kToken);
loop.Run();
remote_channel->AcceptInvitee(kRemoteNodeName, kToken);
base::RunLoop error_loop;
EXPECT_CALL(remote_delegate_, OnChannelError).WillOnce([&] {
error_loop.Quit();
});
local_channel.reset();
error_loop.Run();
}
TEST_F(NodeChannelTest, MessagesCannotBeSmallerThanOldestVersion) {
base::test::TaskEnvironment task_environment;
PlatformChannel channel;
auto local_channel =
CreateNodeChannel(&local_delegate_, channel.TakeLocalEndpoint());
local_channel->Start();
auto remote_channel =
CreateNodeChannel(&remote_delegate_, channel.TakeRemoteEndpoint());
remote_channel->Start();
base::RunLoop loop;
EXPECT_CALL(local_delegate_, OnRequestPortMerge(_, _, _)).Times(0);
const NodeName kRemoteNodeName{123, 456};
const NodeName kToken{987, 654};
EXPECT_CALL(local_delegate_,
OnAcceptInvitee(ports::kInvalidNodeName, kRemoteNodeName, kToken))
.WillRepeatedly([&] { loop.Quit(); });
int payload_size = 1;
int capacity = 8 + payload_size;
auto message =
Channel::Message::CreateMessage(capacity, capacity, 0);
memset(message->mutable_payload(), 0, capacity);
*reinterpret_cast<uint32_t*>(message->mutable_payload()) = 6;
remote_channel->SendChannelMessage(std::move(message));
remote_channel->AcceptInvitee(kRemoteNodeName, kToken);
loop.Run();
remote_channel->ShutDown();
local_channel->ShutDown();
}
}
}
}