/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "src/ipc/host_impl.h"

#include <memory>

#include "perfetto/ext/base/file_utils.h"
#include "perfetto/ext/base/scoped_file.h"
#include "perfetto/ext/base/sys_types.h"
#include "perfetto/ext/base/temp_file.h"
#include "perfetto/ext/base/unix_socket.h"
#include "perfetto/ext/base/utils.h"
#include "perfetto/ext/ipc/service.h"
#include "perfetto/ext/ipc/service_descriptor.h"
#include "src/base/test/test_task_runner.h"
#include "src/ipc/buffered_frame_deserializer.h"
#include "src/ipc/test/test_socket.h"
#include "test/gtest_and_gmock.h"

#include "protos/perfetto/ipc/wire_protocol.gen.h"
#include "src/ipc/test/client_unittest_messages.gen.h"

#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
#include <sys/socket.h>
#endif

namespace perfetto {
namespace ipc {
namespace {

using ::perfetto::ipc::Frame;
using ::perfetto::ipc::gen::ReplyProto;
using ::perfetto::ipc::gen::RequestProto;
using ::testing::_;
using ::testing::Invoke;
using ::testing::InvokeWithoutArgs;
using ::testing::Return;

ipc::TestSocket kTestSocket{"host_impl_unittest"};

// RequestProto and ReplyProto are defined in client_unittest_messages.proto.

class FakeService : public Service {
 public:
  MOCK_METHOD(void, OnFakeMethod1, (const RequestProto&, DeferredBase*));

  static void Invoker(Service* service,
                      const ProtoMessage& req,
                      DeferredBase deferred_reply) {
    static_cast<FakeService*>(service)->OnFakeMethod1(
        static_cast<const RequestProto&>(req), &deferred_reply);
  }

  static std::unique_ptr<ProtoMessage> RequestDecoder(
      const std::string& proto) {
    std::unique_ptr<ProtoMessage> reply(new RequestProto());
    EXPECT_TRUE(reply->ParseFromString(proto));
    return reply;
  }

  explicit FakeService(const char* service_name) {
    descriptor_.service_name = service_name;
    descriptor_.methods.push_back(
        {"FakeMethod1", &RequestDecoder, nullptr, &Invoker});
  }

  const ServiceDescriptor& GetDescriptor() override { return descriptor_; }

  base::ScopedFile TakeReceivedFD() { return ipc::Service::TakeReceivedFD(); }

  base::ScopedFile received_fd_;
  ServiceDescriptor descriptor_;
};

class FakeClient : public base::UnixSocket::EventListener {
 public:
  MOCK_METHOD(void, OnConnect, ());
  MOCK_METHOD(void, OnDisconnect, ());
  MOCK_METHOD(void, OnServiceBound, (const Frame::BindServiceReply&));
  MOCK_METHOD(void, OnInvokeMethodReply, (const Frame::InvokeMethodReply&));
  MOCK_METHOD(void, OnFileDescriptorReceived, (int));
  MOCK_METHOD(void, OnRequestError, ());

  explicit FakeClient(base::TaskRunner* task_runner) {
    sock_ = base::UnixSocket::Connect(kTestSocket.name(), this, task_runner,
                                      kTestSocket.family(),
                                      base::SockType::kStream);
  }

  FakeClient(const char* sock_name, base::TaskRunner* task_runner) {
    auto sock_family = base::GetSockFamily(sock_name);
    sock_ = base::UnixSocket::Connect(sock_name, this, task_runner, sock_family,
                                      base::SockType::kStream);
  }

  FakeClient(base::ScopedSocketHandle connected_socket,
             base::TaskRunner* task_runner) {
    sock_ = base::UnixSocket::AdoptConnected(std::move(connected_socket), this,
                                             task_runner, kTestSocket.family(),
                                             base::SockType::kStream);
    task_runner->PostTask([this]() { OnConnect(); });
  }

  ~FakeClient() override = default;

  void BindService(const std::string& service_name) {
    Frame frame;
    uint64_t request_id = requests_.empty() ? 1 : requests_.rbegin()->first + 1;
    requests_.emplace(request_id, 0);
    frame.set_request_id(request_id);
    frame.mutable_msg_bind_service()->set_service_name(service_name);
    SendFrame(frame);
  }

#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
  void SetPeerIdentity(uid_t uid,
                       pid_t pid,
                       const std::string& machine_id_hint) {
    Frame ipc_frame;
    ipc_frame.set_request_id(0);
    auto* set_peer_identity = ipc_frame.mutable_set_peer_identity();
    set_peer_identity->set_pid(pid);
    set_peer_identity->set_uid(static_cast<int32_t>(uid));
    set_peer_identity->set_machine_id_hint(machine_id_hint);
    SendFrame(ipc_frame);
  }
#endif

  void InvokeMethod(ServiceID service_id,
                    MethodID method_id,
                    const ProtoMessage& args,
                    bool drop_reply = false,
                    int fd = -1) {
    Frame frame;
    uint64_t request_id = requests_.empty() ? 1 : requests_.rbegin()->first + 1;
    requests_.emplace(request_id, 0);
    frame.set_request_id(request_id);
    frame.mutable_msg_invoke_method()->set_service_id(service_id);
    frame.mutable_msg_invoke_method()->set_method_id(method_id);
    frame.mutable_msg_invoke_method()->set_drop_reply(drop_reply);
    frame.mutable_msg_invoke_method()->set_args_proto(args.SerializeAsString());
    SendFrame(frame, fd);
  }

  // base::UnixSocket::EventListener implementation.
  void OnConnect(base::UnixSocket*, bool success) override {
    ASSERT_TRUE(success);
    OnConnect();
  }

  void OnDisconnect(base::UnixSocket*) override { OnDisconnect(); }

  void OnDataAvailable(base::UnixSocket* sock) override {
    ASSERT_EQ(sock_.get(), sock);
    auto buf = frame_deserializer_.BeginReceive();
    base::ScopedFile fd;
    size_t rsize = sock->Receive(buf.data, buf.size, &fd);
    ASSERT_TRUE(frame_deserializer_.EndReceive(rsize));
    if (fd)
      OnFileDescriptorReceived(*fd);
    while (std::unique_ptr<Frame> frame = frame_deserializer_.PopNextFrame()) {
      ASSERT_EQ(1u, requests_.count(frame->request_id()));
      EXPECT_EQ(0, requests_[frame->request_id()]++);
      if (frame->has_msg_bind_service_reply()) {
        if (frame->msg_bind_service_reply().success())
          last_bound_service_id_ = frame->msg_bind_service_reply().service_id();
        return OnServiceBound(frame->msg_bind_service_reply());
      }
      if (frame->has_msg_invoke_method_reply())
        return OnInvokeMethodReply(frame->msg_invoke_method_reply());
      if (frame->has_msg_request_error())
        return OnRequestError();
      FAIL() << "Unexpected frame received from host";
    }
  }

  void SendFrame(const Frame& frame, int fd = -1) {
    std::string buf = BufferedFrameDeserializer::Serialize(frame);
    ASSERT_TRUE(sock_->Send(buf.data(), buf.size(), fd));
  }

  BufferedFrameDeserializer frame_deserializer_;
  std::unique_ptr<base::UnixSocket> sock_;
  std::map<uint64_t /* request_id */, int /* num_replies_received */> requests_;
  ServiceID last_bound_service_id_;
};

class HostImplTest : public ::testing::Test {
 public:
  void SetUp() override {
    kTestSocket.Destroy();
    task_runner_.reset(new base::TestTaskRunner());
#if PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
    Host* host = Host::CreateInstance_Fuchsia(task_runner_.get()).release();
    auto socket_pair = base::UnixSocketRaw::CreatePairPosix(
        base::SockFamily::kUnix, base::SockType::kStream);
    host->AdoptConnectedSocket_Fuchsia(
        base::ScopedSocketHandle(socket_pair.first.ReleaseFd()),
        [](int) { return false; });
    cli_.reset(
        new FakeClient(base::ScopedSocketHandle(socket_pair.second.ReleaseFd()),
                       task_runner_.get()));
#else
    Host* host =
        Host::CreateInstance(kTestSocket.name(), task_runner_.get()).release();
    cli_.reset(new FakeClient(task_runner_.get()));
#endif
    ASSERT_NE(nullptr, host);
    host_.reset(static_cast<HostImpl*>(host));
    auto on_connect = task_runner_->CreateCheckpoint("on_connect");
    EXPECT_CALL(*cli_, OnConnect()).WillOnce(Invoke(on_connect));
    task_runner_->RunUntilCheckpoint("on_connect");
  }

  void TearDown() override {
    task_runner_->RunUntilIdle();
    cli_.reset();
    host_.reset();
    task_runner_->RunUntilIdle();
    task_runner_.reset();
    kTestSocket.Destroy();
  }

  // ::testing::StrictMock<MockEventListener> proxy_events_;
  std::unique_ptr<base::TestTaskRunner> task_runner_;
  std::unique_ptr<HostImpl> host_;
  std::unique_ptr<FakeClient> cli_;
};

TEST_F(HostImplTest, BindService) {
  // First bind the service when it doesn't exists yet and check that the
  // BindService() request fails.
  cli_->BindService("FakeService");  // FakeService does not exist yet.
  auto on_bind_failure = task_runner_->CreateCheckpoint("on_bind_failure");
  EXPECT_CALL(*cli_, OnServiceBound(_))
      .WillOnce(Invoke([on_bind_failure](const Frame::BindServiceReply& reply) {
        ASSERT_FALSE(reply.success());
        on_bind_failure();
      }));
  task_runner_->RunUntilCheckpoint("on_bind_failure");

  // Now expose the service and bind it.
  ASSERT_TRUE(host_->ExposeService(
      std::unique_ptr<Service>(new FakeService("FakeService"))));
  auto on_bind_success = task_runner_->CreateCheckpoint("on_bind_success");
  cli_->BindService("FakeService");
  EXPECT_CALL(*cli_, OnServiceBound(_))
      .WillOnce(Invoke([on_bind_success](const Frame::BindServiceReply& reply) {
        ASSERT_TRUE(reply.success());
        on_bind_success();
      }));
  task_runner_->RunUntilCheckpoint("on_bind_success");
}

TEST_F(HostImplTest, InvokeNonExistingMethod) {
  FakeService* fake_service = new FakeService("FakeService");
  ASSERT_TRUE(host_->ExposeService(std::unique_ptr<Service>(fake_service)));
  auto on_bind = task_runner_->CreateCheckpoint("on_bind");
  cli_->BindService("FakeService");
  EXPECT_CALL(*cli_, OnServiceBound(_)).WillOnce(InvokeWithoutArgs(on_bind));
  task_runner_->RunUntilCheckpoint("on_bind");

  auto on_invoke_failure = task_runner_->CreateCheckpoint("on_invoke_failure");
  cli_->InvokeMethod(cli_->last_bound_service_id_, 42, RequestProto());
  EXPECT_CALL(*cli_, OnInvokeMethodReply(_))
      .WillOnce(
          Invoke([on_invoke_failure](const Frame::InvokeMethodReply& reply) {
            ASSERT_FALSE(reply.success());
            ASSERT_FALSE(reply.has_more());
            on_invoke_failure();
          }));
  task_runner_->RunUntilCheckpoint("on_invoke_failure");
}

TEST_F(HostImplTest, InvokeMethod) {
  FakeService* fake_service = new FakeService("FakeService");
  ASSERT_TRUE(host_->ExposeService(std::unique_ptr<Service>(fake_service)));
  auto on_bind = task_runner_->CreateCheckpoint("on_bind");
  cli_->BindService("FakeService");
  EXPECT_CALL(*cli_, OnServiceBound(_)).WillOnce(InvokeWithoutArgs(on_bind));
  task_runner_->RunUntilCheckpoint("on_bind");

  RequestProto req_args;
  req_args.set_data("foo");
  cli_->InvokeMethod(cli_->last_bound_service_id_, 1, req_args);
  auto on_reply_sent = task_runner_->CreateCheckpoint("on_reply_sent");
  EXPECT_CALL(*fake_service, OnFakeMethod1(_, _))
      .WillOnce(
          Invoke([on_reply_sent](const RequestProto& req, DeferredBase* reply) {
            ASSERT_EQ("foo", req.data());
            std::unique_ptr<ReplyProto> reply_args(new ReplyProto());
            reply_args->set_data("bar");
            reply->Resolve(AsyncResult<ProtoMessage>(
                std::unique_ptr<ProtoMessage>(reply_args.release())));
            on_reply_sent();
          }));
  task_runner_->RunUntilCheckpoint("on_reply_sent");

  auto on_reply_received = task_runner_->CreateCheckpoint("on_reply_received");
  EXPECT_CALL(*cli_, OnInvokeMethodReply(_))
      .WillOnce(
          Invoke([on_reply_received](const Frame::InvokeMethodReply& reply) {
            ASSERT_TRUE(reply.success());
            ASSERT_FALSE(reply.has_more());
            ReplyProto reply_args;
            reply_args.ParseFromString(reply.reply_proto());
            ASSERT_EQ("bar", reply_args.data());
            on_reply_received();
          }));
  task_runner_->RunUntilCheckpoint("on_reply_received");
}

TEST_F(HostImplTest, InvokeMethodDropReply) {
  FakeService* fake_service = new FakeService("FakeService");
  ASSERT_TRUE(host_->ExposeService(std::unique_ptr<Service>(fake_service)));
  auto on_bind = task_runner_->CreateCheckpoint("on_bind");
  cli_->BindService("FakeService");
  EXPECT_CALL(*cli_, OnServiceBound(_)).WillOnce(InvokeWithoutArgs(on_bind));
  task_runner_->RunUntilCheckpoint("on_bind");

  // OnFakeMethod1 will:
  // - Do nothing on the 1st call, when |drop_reply| == true.
  // - Reply on the 2nd call, when |drop_reply| == false.
  EXPECT_CALL(*fake_service, OnFakeMethod1(_, _))
      .Times(2)
      .WillRepeatedly(Invoke([](const RequestProto& req, DeferredBase* reply) {
        if (req.data() == "drop_reply")
          return;
        std::unique_ptr<ReplyProto> reply_args(new ReplyProto());
        reply_args->set_data("the_reply");
        reply->Resolve(AsyncResult<ProtoMessage>(
            std::unique_ptr<ProtoMessage>(reply_args.release())));
      }));

  auto on_reply_received = task_runner_->CreateCheckpoint("on_reply_received");
  EXPECT_CALL(*cli_, OnInvokeMethodReply(_))
      .WillOnce(
          Invoke([on_reply_received](const Frame::InvokeMethodReply& reply) {
            ASSERT_TRUE(reply.success());
            ReplyProto reply_args;
            reply_args.ParseFromString(reply.reply_proto());
            ASSERT_EQ("the_reply", reply_args.data());
            on_reply_received();
          }));

  // Invoke the method first with |drop_reply|=true, then |drop_reply|=false.
  RequestProto rp;
  rp.set_data("drop_reply");
  cli_->InvokeMethod(cli_->last_bound_service_id_, 1, rp, true /*drop_reply*/);
  rp.set_data("do_reply");
  cli_->InvokeMethod(cli_->last_bound_service_id_, 1, rp, false /*drop_reply*/);

  task_runner_->RunUntilCheckpoint("on_reply_received");
}

#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && \
    !PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
// File descriptor sending over IPC is not supported on Windows.
TEST_F(HostImplTest, SendFileDescriptor) {
  FakeService* fake_service = new FakeService("FakeService");
  ASSERT_TRUE(host_->ExposeService(std::unique_ptr<Service>(fake_service)));
  auto on_bind = task_runner_->CreateCheckpoint("on_bind");
  cli_->BindService("FakeService");
  EXPECT_CALL(*cli_, OnServiceBound(_)).WillOnce(InvokeWithoutArgs(on_bind));
  task_runner_->RunUntilCheckpoint("on_bind");

  static constexpr char kFileContent[] = "shared file";
  RequestProto req_args;
  cli_->InvokeMethod(cli_->last_bound_service_id_, 1, req_args);
  auto on_reply_sent = task_runner_->CreateCheckpoint("on_reply_sent");
  base::TempFile tx_file = base::TempFile::CreateUnlinked();
  ASSERT_EQ(static_cast<size_t>(base::WriteAll(tx_file.fd(), kFileContent,
                                               sizeof(kFileContent))),
            sizeof(kFileContent));
  EXPECT_CALL(*fake_service, OnFakeMethod1(_, _))
      .WillOnce(Invoke(
          [on_reply_sent, &tx_file](const RequestProto&, DeferredBase* reply) {
            std::unique_ptr<ReplyProto> reply_args(new ReplyProto());
            auto async_res = AsyncResult<ProtoMessage>(
                std::unique_ptr<ProtoMessage>(reply_args.release()));
            async_res.set_fd(tx_file.fd());
            reply->Resolve(std::move(async_res));
            on_reply_sent();
          }));
  task_runner_->RunUntilCheckpoint("on_reply_sent");
  tx_file.ReleaseFD();

  auto on_fd_received = task_runner_->CreateCheckpoint("on_fd_received");
  EXPECT_CALL(*cli_, OnFileDescriptorReceived(_))
      .WillOnce(Invoke([on_fd_received](int fd) {
        char buf[sizeof(kFileContent)] = {};
        ASSERT_EQ(0, lseek(fd, 0, SEEK_SET));
        ASSERT_EQ(static_cast<int32_t>(sizeof(buf)),
                  PERFETTO_EINTR(read(fd, buf, sizeof(buf))));
        ASSERT_STREQ(kFileContent, buf);
        on_fd_received();
      }));
  EXPECT_CALL(*cli_, OnInvokeMethodReply(_));
  task_runner_->RunUntilCheckpoint("on_fd_received");
}

TEST_F(HostImplTest, ReceiveFileDescriptor) {
  auto received = task_runner_->CreateCheckpoint("received");
  FakeService* fake_service = new FakeService("FakeService");
  ASSERT_TRUE(host_->ExposeService(std::unique_ptr<Service>(fake_service)));
  auto on_bind = task_runner_->CreateCheckpoint("on_bind");
  cli_->BindService("FakeService");
  EXPECT_CALL(*cli_, OnServiceBound(_)).WillOnce(InvokeWithoutArgs(on_bind));
  task_runner_->RunUntilCheckpoint("on_bind");

  static constexpr char kFileContent[] = "shared file";
  RequestProto req_args;
  base::TempFile tx_file = base::TempFile::CreateUnlinked();
  ASSERT_EQ(static_cast<size_t>(base::WriteAll(tx_file.fd(), kFileContent,
                                               sizeof(kFileContent))),
            sizeof(kFileContent));
  cli_->InvokeMethod(cli_->last_bound_service_id_, 1, req_args, false,
                     tx_file.fd());
  EXPECT_CALL(*cli_, OnInvokeMethodReply(_));
  base::ScopedFile rx_fd;
  EXPECT_CALL(*fake_service, OnFakeMethod1(_, _))
      .WillOnce(Invoke([received, &fake_service, &rx_fd](const RequestProto&,
                                                         DeferredBase*) {
        rx_fd = fake_service->TakeReceivedFD();
        received();
      }));

  task_runner_->RunUntilCheckpoint("received");

  ASSERT_TRUE(rx_fd);
  char buf[sizeof(kFileContent)] = {};
  ASSERT_EQ(0, lseek(*rx_fd, 0, SEEK_SET));
  ASSERT_EQ(static_cast<int32_t>(sizeof(buf)),
            PERFETTO_EINTR(read(*rx_fd, buf, sizeof(buf))));
  ASSERT_STREQ(kFileContent, buf);
}
#endif  // !OS_WIN

// Invoke a method and immediately after disconnect the client.
TEST_F(HostImplTest, OnClientDisconnect) {
  FakeService* fake_service = new FakeService("FakeService");
  ASSERT_TRUE(host_->ExposeService(std::unique_ptr<Service>(fake_service)));
  auto on_bind = task_runner_->CreateCheckpoint("on_bind");
  cli_->BindService("FakeService");
  EXPECT_CALL(*cli_, OnServiceBound(_)).WillOnce(InvokeWithoutArgs(on_bind));
  task_runner_->RunUntilCheckpoint("on_bind");

  RequestProto req_args;
  req_args.set_data("foo");
  cli_->InvokeMethod(cli_->last_bound_service_id_, 1, req_args);
  EXPECT_CALL(*cli_, OnInvokeMethodReply(_)).Times(0);
  cli_.reset();  // Disconnect the client.
  auto on_host_method = task_runner_->CreateCheckpoint("on_host_method");
  EXPECT_CALL(*fake_service, OnFakeMethod1(_, _))
      .WillOnce(
          Invoke([on_host_method](const RequestProto& req, DeferredBase*) {
            ASSERT_EQ("foo", req.data());
            on_host_method();
          }));
  task_runner_->RunUntilCheckpoint("on_host_method");
}

// Like InvokeMethod, but instead of resolving the Deferred reply within the
// call stack, std::move()-s it outside an replies
TEST_F(HostImplTest, MoveReplyObjectAndReplyAsynchronously) {
  FakeService* fake_service = new FakeService("FakeService");
  ASSERT_TRUE(host_->ExposeService(std::unique_ptr<Service>(fake_service)));
  auto on_bind = task_runner_->CreateCheckpoint("on_bind");
  cli_->BindService("FakeService");
  EXPECT_CALL(*cli_, OnServiceBound(_)).WillOnce(InvokeWithoutArgs(on_bind));
  task_runner_->RunUntilCheckpoint("on_bind");

  // Invokes the remote method and waits that the FakeService sees it. The reply
  // is not resolved but just moved into |moved_reply|.
  RequestProto req_args;
  cli_->InvokeMethod(cli_->last_bound_service_id_, 1, req_args);
  auto on_invoke = task_runner_->CreateCheckpoint("on_invoke");
  DeferredBase moved_reply;
  EXPECT_CALL(*fake_service, OnFakeMethod1(_, _))
      .WillOnce(Invoke(
          [on_invoke, &moved_reply](const RequestProto&, DeferredBase* reply) {
            moved_reply = std::move(*reply);
            on_invoke();
          }));
  task_runner_->RunUntilCheckpoint("on_invoke");

  // Check that the FakeClient doesn't see any reply yet.
  EXPECT_CALL(*cli_, OnInvokeMethodReply(_)).Times(0);
  task_runner_->RunUntilIdle();
  ASSERT_TRUE(::testing::Mock::VerifyAndClearExpectations(cli_.get()));

  // Resolve the reply asynchronously in a deferred task.
  task_runner_->PostTask([&moved_reply] {
    std::unique_ptr<ReplyProto> reply_args(new ReplyProto());
    reply_args->set_data("bar");
    moved_reply.Resolve(AsyncResult<ProtoMessage>(
        std::unique_ptr<ProtoMessage>(reply_args.release())));
  });

  auto on_reply_received = task_runner_->CreateCheckpoint("on_reply_received");
  EXPECT_CALL(*cli_, OnInvokeMethodReply(_))
      .WillOnce(
          Invoke([on_reply_received](const Frame::InvokeMethodReply& reply) {
            ASSERT_TRUE(reply.success());
            ASSERT_FALSE(reply.has_more());
            ReplyProto reply_args;
            reply_args.ParseFromString(reply.reply_proto());
            ASSERT_EQ("bar", reply_args.data());
            on_reply_received();
          }));
  task_runner_->RunUntilCheckpoint("on_reply_received");
}

#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
// Check ClientInfo of the service.
TEST_F(HostImplTest, ServiceClientInfo) {
  FakeService* fake_service = new FakeService("FakeService");
  ASSERT_TRUE(host_->ExposeService(std::unique_ptr<Service>(fake_service)));
  auto on_bind = task_runner_->CreateCheckpoint("on_bind");
  cli_->BindService("FakeService");
  EXPECT_CALL(*cli_, OnServiceBound(_)).WillOnce(InvokeWithoutArgs(on_bind));
  task_runner_->RunUntilCheckpoint("on_bind");

  RequestProto req_args;
  req_args.set_data("foo");
  cli_->InvokeMethod(cli_->last_bound_service_id_, 1, req_args);
  EXPECT_CALL(*fake_service, OnFakeMethod1(_, _))
      .WillOnce(
          Invoke([fake_service](const RequestProto& req, DeferredBase* reply) {
            ASSERT_EQ("foo", req.data());
            std::unique_ptr<ReplyProto> reply_args(new ReplyProto());
            reply_args->set_data("bar");
            reply->Resolve(AsyncResult<ProtoMessage>(
                std::unique_ptr<ProtoMessage>(reply_args.release())));
            // Verifies the pid() and uid() values in ClientInfo.
            const auto& client_info = fake_service->client_info();
            ASSERT_EQ(client_info.uid(), getuid());
            ASSERT_EQ(client_info.pid(), getpid());
          }));

  EXPECT_CALL(*cli_, OnInvokeMethodReply(_)).WillOnce(Return());
  task_runner_->RunUntilIdle();
}

TEST_F(HostImplTest, SetPeerIdentityUnixSocket) {
  FakeService* fake_service = new FakeService("FakeService");
  ASSERT_TRUE(host_->ExposeService(std::unique_ptr<Service>(fake_service)));
  // SetPeerIdentity must be the first message. Use getpid()+1/geteuid+1 to
  // check that this message doesn't take effect for Unix socket.
  cli_->SetPeerIdentity(geteuid() + 1, getpid() + 1, "test_machine_id_hint");

  auto on_bind = task_runner_->CreateCheckpoint("on_bind");
  cli_->BindService("FakeService");
  EXPECT_CALL(*cli_, OnServiceBound(_)).WillOnce(InvokeWithoutArgs(on_bind));
  task_runner_->RunUntilCheckpoint("on_bind");

  RequestProto req_args;
  req_args.set_data("foo");
  cli_->InvokeMethod(cli_->last_bound_service_id_, 1, req_args);
  EXPECT_CALL(*fake_service, OnFakeMethod1(_, _))
      .WillOnce(
          Invoke([fake_service](const RequestProto& req, DeferredBase* reply) {
            ASSERT_EQ("foo", req.data());
            std::unique_ptr<ReplyProto> reply_args(new ReplyProto());
            reply_args->set_data("bar");
            reply->Resolve(AsyncResult<ProtoMessage>(
                std::unique_ptr<ProtoMessage>(reply_args.release())));
            // Verifies the pid() and uid() values in ClientInfo.
            const auto& client_info = fake_service->client_info();
            ASSERT_EQ(client_info.uid(), getuid());
            ASSERT_EQ(client_info.pid(), getpid());
            ASSERT_EQ(client_info.machine_id(), base::kDefaultMachineID);
          }));

  EXPECT_CALL(*cli_, OnInvokeMethodReply(_)).WillOnce(Return());
  task_runner_->RunUntilIdle();
}

TEST(HostImpl, SetPeerIdentityTcpSocket) {
  std::unique_ptr<base::TestTaskRunner> task_runner(new base::TestTaskRunner());
  std::unique_ptr<HostImpl> host_impl;
  std::unique_ptr<FakeClient> cli;

  auto tear_down = base::OnScopeExit([&]() {
    task_runner->RunUntilIdle();
    cli.reset();
    host_impl.reset();
    task_runner->RunUntilIdle();
    task_runner.reset();
  });

  Host* host = Host::CreateInstance("127.0.0.1:0", task_runner.get()).release();
  ASSERT_NE(nullptr, host);
  host_impl.reset(static_cast<HostImpl*>(host));

  auto sock_name = host_impl->sock()->GetSockAddr();
  cli.reset(new FakeClient(sock_name.c_str(), task_runner.get()));

  auto on_connect = task_runner->CreateCheckpoint("on_connect");
  EXPECT_CALL(*cli, OnConnect()).WillOnce(Invoke(on_connect));
  task_runner->RunUntilCheckpoint("on_connect");

  FakeService* fake_service = new FakeService("FakeService");
  ASSERT_TRUE(host->ExposeService(std::unique_ptr<Service>(fake_service)));
  // Set peer identity with fake values.
  cli->SetPeerIdentity(123, 456, "test_machine_id_hint");

  auto on_bind = task_runner->CreateCheckpoint("on_bind");
  cli->BindService("FakeService");
  EXPECT_CALL(*cli, OnServiceBound(_)).WillOnce(InvokeWithoutArgs(on_bind));
  task_runner->RunUntilCheckpoint("on_bind");

  RequestProto req_args;
  req_args.set_data("foo");
  cli->InvokeMethod(cli->last_bound_service_id_, 1, req_args);
  EXPECT_CALL(*fake_service, OnFakeMethod1(_, _))
      .WillOnce(
          Invoke([fake_service](const RequestProto& req, DeferredBase* reply) {
            ASSERT_EQ("foo", req.data());
            std::unique_ptr<ReplyProto> reply_args(new ReplyProto());
            reply_args->set_data("bar");
            reply->Resolve(AsyncResult<ProtoMessage>(
                std::unique_ptr<ProtoMessage>(reply_args.release())));
            // Verify peer identity.
            const auto& client_info = fake_service->client_info();
            ASSERT_EQ(client_info.uid(), 123u);
            ASSERT_EQ(client_info.pid(), 456);
            // ClientInfo contains non-default raw machine ID.
            ASSERT_NE(client_info.machine_id(), base::kDefaultMachineID);
          }));

  EXPECT_CALL(*cli, OnInvokeMethodReply(_)).WillOnce(Return());
  task_runner->RunUntilIdle();
}
#endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||
        // PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)

// TODO(primiano): add the tests below in next CLs.
// TEST(HostImplTest, ManyClients) {}
// TEST(HostImplTest, OverlappingRequstsOutOfOrder) {}
// TEST(HostImplTest, StreamingRequest) {}
// TEST(HostImplTest, ManyDropReplyRequestsDontLeakMemory) {}

}  // namespace
}  // namespace ipc
}  // namespace perfetto
