// Copyright 2018 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <fcntl.h>
#include <poll.h>
#include <sys/stat.h>
#include <unistd.h>
#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include <base/bind.h>
#include <base/callback.h>
#include <base/files/file_path.h>
#include <base/files/scoped_file.h>
#include <base/files/scoped_temp_dir.h>
#include <base/logging.h>
#include <base/memory/ref_counted.h>
#include <base/memory/shared_memory.h>
#include <base/message_loop/message_loop.h>
#include <base/run_loop.h>
#include <base/strings/stringprintf.h>
#include <brillo/dbus/async_event_sequencer.h>
#include <dbus/diagnosticsd/dbus-constants.h>
#include <dbus/message.h>
#include <dbus/mock_bus.h>
#include <dbus/mock_exported_object.h>
#include <dbus/mock_object_proxy.h>
#include <dbus/property.h>
#include <gmock/gmock.h>
#include <google/protobuf/util/message_differencer.h>
#include <gtest/gtest.h>
#include <mojo/edk/embedder/embedder.h>
#include <mojo/public/cpp/bindings/binding.h>
#include <mojo/public/cpp/bindings/interface_ptr.h>

#include "diagnostics/diagnosticsd/diagnosticsd_core.h"
#include "diagnostics/diagnosticsd/ec_constants.h"
#include "diagnostics/diagnosticsd/fake_browser.h"
#include "diagnostics/diagnosticsd/fake_diagnostics_processor.h"
#include "diagnostics/diagnosticsd/file_test_utils.h"
#include "diagnostics/diagnosticsd/mojo_test_utils.h"
#include "diagnostics/diagnosticsd/mojo_utils.h"
#include "diagnostics/diagnosticsd/protobuf_test_utils.h"
#include "diagnosticsd.pb.h"  // NOLINT(build/include)
#include "mojo/diagnosticsd.mojom.h"

using testing::_;
using testing::Invoke;
using testing::Mock;
using testing::Return;
using testing::SaveArg;
using testing::StrictMock;
using testing::WithArg;

namespace diagnostics {

// Templates for the gRPC URIs that should be used for testing. "%s" is
// substituted with a temporary directory.
const char kDiagnosticsdGrpcUriTemplate[] = "unix:%s/test_diagnosticsd_socket";
const char kDiagnosticsProcessorGrpcUriTemplate[] =
    "unix:%s/test_diagnostics_processor_socket";
const char kUiMessageReceiverDiagnosticsProcessorGrpcUriTemplate[] =
    "unix:%s/test_ui_message_receiver_diagnostics_processor_socket";

using MojomDiagnosticsdService =
    chromeos::diagnosticsd::mojom::DiagnosticsdService;
using MojomDiagnosticsdServiceFactory =
    chromeos::diagnosticsd::mojom::DiagnosticsdServiceFactory;

namespace {

// Returns a callback that, once called, saves its parameter to |*response| and
// quits |*run_loop|.
template <typename ValueType>
base::Callback<void(std::unique_ptr<ValueType>)> MakeAsyncResponseWriter(
    std::unique_ptr<ValueType>* response, base::RunLoop* run_loop) {
  return base::Bind(
      [](std::unique_ptr<ValueType>* response, base::RunLoop* run_loop,
         std::unique_ptr<ValueType> received_response) {
        EXPECT_TRUE(received_response);
        EXPECT_FALSE(*response);
        *response = std::move(received_response);
        run_loop->Quit();
      },
      base::Unretained(response), base::Unretained(run_loop));
}

class MockDiagnosticsdCoreDelegate : public DiagnosticsdCore::Delegate {
 public:
  std::unique_ptr<mojo::Binding<MojomDiagnosticsdServiceFactory>>
  BindDiagnosticsdMojoServiceFactory(
      MojomDiagnosticsdServiceFactory* mojo_service_factory,
      base::ScopedFD mojo_pipe_fd) override {
    // Redirect to a separate mockable method to workaround GMock's issues with
    // move-only types.
    return std::unique_ptr<mojo::Binding<MojomDiagnosticsdServiceFactory>>(
        BindDiagnosticsdMojoServiceFactoryImpl(mojo_service_factory,
                                               mojo_pipe_fd.get()));
  }

  MOCK_METHOD2(BindDiagnosticsdMojoServiceFactoryImpl,
               mojo::Binding<MojomDiagnosticsdServiceFactory>*(
                   MojomDiagnosticsdServiceFactory* mojo_service_factory,
                   int mojo_pipe_fd));
  MOCK_METHOD0(BeginDaemonShutdown, void());
};

// Tests for the DiagnosticsdCore class.
class DiagnosticsdCoreTest : public testing::Test {
 protected:
  DiagnosticsdCoreTest() { InitializeMojo(); }

  ~DiagnosticsdCoreTest() { SetDBusShutdownExpectations(); }

  void SetUp() override {
    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());

    diagnosticsd_grpc_uri_ = base::StringPrintf(
        kDiagnosticsdGrpcUriTemplate, temp_dir_.GetPath().value().c_str());
    ui_message_receiver_diagnostics_processor_grpc_uri_ = base::StringPrintf(
        kUiMessageReceiverDiagnosticsProcessorGrpcUriTemplate,
        temp_dir_.GetPath().value().c_str());

    diagnostics_processor_grpc_uri_ =
        base::StringPrintf(kDiagnosticsProcessorGrpcUriTemplate,
                           temp_dir_.GetPath().value().c_str());

    core_ = std::make_unique<DiagnosticsdCore>(
        diagnosticsd_grpc_uri_,
        ui_message_receiver_diagnostics_processor_grpc_uri_,
        std::vector<std::string>{diagnostics_processor_grpc_uri_},
        &core_delegate_);
    core_->set_root_dir_for_testing(temp_dir_.GetPath());

    SetUpEcEventService();

    ASSERT_TRUE(core_->Start());

    SetUpEcEventServiceFifoWriteEnd();

    SetUpDBus();

    fake_browser_ =
        std::make_unique<FakeBrowser>(&mojo_service_factory_interface_ptr_,
                                      bootstrap_mojo_connection_dbus_method_);
  }

  void TearDown() override {
    base::RunLoop run_loop;
    core_->ShutDown(run_loop.QuitClosure());
    run_loop.Run();
  }

  const base::FilePath& temp_dir_path() const {
    DCHECK(temp_dir_.IsValid());
    return temp_dir_.GetPath();
  }

  MockDiagnosticsdCoreDelegate* core_delegate() { return &core_delegate_; }

  mojo::InterfacePtr<MojomDiagnosticsdServiceFactory>*
  mojo_service_factory_interface_ptr() {
    return &mojo_service_factory_interface_ptr_;
  }

  FakeBrowser* fake_browser() {
    DCHECK(fake_browser_);
    return fake_browser_.get();
  }

  // Set up mock for BindDiagnosticsdMojoServiceFactory() that simulates
  // successful Mojo service binding to the given file descriptor. After the
  // mock gets triggered, |mojo_service_factory_interface_ptr_| become
  // initialized to point to the tested Mojo service.
  void SetSuccessMockBindDiagnosticsdMojoService(
      FakeMojoFdGenerator* fake_mojo_fd_generator) {
    EXPECT_CALL(core_delegate_, BindDiagnosticsdMojoServiceFactoryImpl(_, _))
        .WillOnce(Invoke([fake_mojo_fd_generator, this](
                             MojomDiagnosticsdServiceFactory*
                                 mojo_service_factory,
                             int mojo_pipe_fd) {
          // Verify the file descriptor is a duplicate of an expected one.
          EXPECT_TRUE(fake_mojo_fd_generator->IsDuplicateFd(mojo_pipe_fd));
          // Initialize a Mojo binding that, instead of working through the
          // given (fake) file descriptor, talks to the test endpoint
          // |mojo_service_interface_ptr_|.
          auto mojo_service_factory_binding =
              std::make_unique<mojo::Binding<MojomDiagnosticsdServiceFactory>>(
                  mojo_service_factory, &mojo_service_factory_interface_ptr_);
          DCHECK(mojo_service_factory_interface_ptr_);
          return mojo_service_factory_binding.release();
        }));
  }

  void WriteEcEventToSysfsFile(
      const DiagnosticsdEcEventService::EcEvent& ec_event) const {
    ASSERT_EQ(write(ec_event_service_fd_.get(), &ec_event, sizeof(ec_event)),
              sizeof(ec_event));
  }

  dbus::ExportedObject::MethodCallCallback
  bootstrap_mojo_connection_dbus_method() {
    return bootstrap_mojo_connection_dbus_method_;
  }

  const std::string& diagnosticsd_grpc_uri() const {
    DCHECK(!diagnosticsd_grpc_uri_.empty());
    return diagnosticsd_grpc_uri_;
  }

  const std::string& ui_message_receiver_diagnostics_processor_grpc_uri()
      const {
    DCHECK(!ui_message_receiver_diagnostics_processor_grpc_uri_.empty());
    return ui_message_receiver_diagnostics_processor_grpc_uri_;
  }

  const std::string& diagnostics_processor_grpc_uri() const {
    DCHECK(!diagnostics_processor_grpc_uri_.empty());
    return diagnostics_processor_grpc_uri_;
  }

 private:
  // Initialize the Mojo subsystem.
  void InitializeMojo() { mojo::edk::Init(); }

  // Perform initialization of the D-Bus object exposed by the tested code.
  void SetUpDBus() {
    const dbus::ObjectPath kDBusObjectPath(kDiagnosticsdServicePath);

    // Expect that the /org/chromium/Diagnosticsd object is exported.
    diagnosticsd_dbus_object_ = new StrictMock<dbus::MockExportedObject>(
        dbus_bus_.get(), kDBusObjectPath);
    EXPECT_CALL(*dbus_bus_, GetExportedObject(kDBusObjectPath))
        .WillOnce(Return(diagnosticsd_dbus_object_.get()));

    // Expect that standard methods on the org.freedesktop.DBus.Properties
    // interface are exported.
    EXPECT_CALL(
        *diagnosticsd_dbus_object_,
        ExportMethod(dbus::kPropertiesInterface, dbus::kPropertiesGet, _, _));
    EXPECT_CALL(
        *diagnosticsd_dbus_object_,
        ExportMethod(dbus::kPropertiesInterface, dbus::kPropertiesSet, _, _));
    EXPECT_CALL(*diagnosticsd_dbus_object_,
                ExportMethod(dbus::kPropertiesInterface,
                             dbus::kPropertiesGetAll, _, _));

    // Expect that methods on the org.chromium.DiagnosticsdInterface interface
    // are exported.
    EXPECT_CALL(*diagnosticsd_dbus_object_,
                ExportMethod(kDiagnosticsdServiceInterface,
                             kDiagnosticsdBootstrapMojoConnectionMethod, _, _))
        .WillOnce(SaveArg<2 /* method_call_callback */>(
            &bootstrap_mojo_connection_dbus_method_));

    // Run the tested code that exports D-Bus objects and methods.
    scoped_refptr<brillo::dbus_utils::AsyncEventSequencer> dbus_sequencer(
        new brillo::dbus_utils::AsyncEventSequencer());
    core_->RegisterDBusObjectsAsync(dbus_bus_, dbus_sequencer.get());

    // Verify that required D-Bus methods are exported.
    EXPECT_FALSE(bootstrap_mojo_connection_dbus_method_.is_null());
  }

  // Set mock expectations for calls triggered during test destruction.
  void SetDBusShutdownExpectations() {
    EXPECT_CALL(*diagnosticsd_dbus_object_, Unregister());
  }

  // Creates FIFO to emulates the EC event service sysfs event file.
  void SetUpEcEventService() {
    core_->set_ec_event_service_fd_events_for_testing(POLLIN);
    ASSERT_TRUE(base::CreateDirectory(ec_event_sysfs_file_path().DirName()));
    ASSERT_EQ(mkfifo(ec_event_sysfs_file_path().value().c_str(), 0600), 0);
  }

  // Setups |ec_event_service_fd_| FIFO file descriptor. Must be called only
  // after |DiagnosticsdCore::Start()| call. Otherwise, it will block thread.
  void SetUpEcEventServiceFifoWriteEnd() {
    ASSERT_FALSE(ec_event_service_fd_.is_valid());
    ec_event_service_fd_.reset(
        open(ec_event_sysfs_file_path().value().c_str(), O_WRONLY));
    ASSERT_TRUE(ec_event_service_fd_.is_valid());
  }

  base::FilePath ec_event_sysfs_file_path() const {
    return temp_dir_.GetPath().Append(kEcEventSysfsPath);
  }

  base::MessageLoop message_loop_;

  base::ScopedTempDir temp_dir_;

  // gRPC URI on which the tested "Diagnosticsd" gRPC service (owned by
  // DiagnosticsdCore) is listening.
  std::string diagnosticsd_grpc_uri_;
  // gRPC URI on which the fake "DiagnosticsProcessor" gRPC service (owned by
  // FakeDiagnosticsProcessor) is listening, eligible to receive UI messages.
  std::string ui_message_receiver_diagnostics_processor_grpc_uri_;
  // gRPC URI on which the fake "DiagnosticsProcessor" gRPC service (owned by
  // FakeDiagnosticsProcessor) is listening.
  std::string diagnostics_processor_grpc_uri_;

  scoped_refptr<StrictMock<dbus::MockBus>> dbus_bus_ =
      new StrictMock<dbus::MockBus>(dbus::Bus::Options());

  // Mock D-Bus integration helper for the object exposed by the tested code.
  scoped_refptr<StrictMock<dbus::MockExportedObject>> diagnosticsd_dbus_object_;

  // Mojo interface to the service factory exposed by the tested code.
  mojo::InterfacePtr<MojomDiagnosticsdServiceFactory>
      mojo_service_factory_interface_ptr_;

  // Write end of FIFO that emulates EC sysfs event file. EC event service
  // operates with read end of FIFO as with usual file.
  // Must be initialized only after |DiagnosticsdCore::Start()| call.
  base::ScopedFD ec_event_service_fd_;

  StrictMock<MockDiagnosticsdCoreDelegate> core_delegate_;

  std::unique_ptr<DiagnosticsdCore> core_;

  // Callback that the tested code exposed as the BootstrapMojoConnection D-Bus
  // method.
  dbus::ExportedObject::MethodCallCallback
      bootstrap_mojo_connection_dbus_method_;

  std::unique_ptr<FakeBrowser> fake_browser_;
};

}  // namespace

// Test that the Mojo service gets successfully bootstrapped after the
// BootstrapMojoConnection D-Bus method is called.
TEST_F(DiagnosticsdCoreTest, MojoBootstrapSuccess) {
  FakeMojoFdGenerator fake_mojo_fd_generator;
  SetSuccessMockBindDiagnosticsdMojoService(&fake_mojo_fd_generator);

  EXPECT_TRUE(fake_browser()->BootstrapMojoConnection(&fake_mojo_fd_generator));

  EXPECT_TRUE(*mojo_service_factory_interface_ptr());
}

// Test failure to bootstrap the Mojo service due to en error returned by
// BindDiagnosticsdMojoService() delegate method.
TEST_F(DiagnosticsdCoreTest, MojoBootstrapErrorToBind) {
  FakeMojoFdGenerator fake_mojo_fd_generator;
  EXPECT_CALL(*core_delegate(), BindDiagnosticsdMojoServiceFactoryImpl(_, _))
      .WillOnce(Return(nullptr));
  EXPECT_CALL(*core_delegate(), BeginDaemonShutdown());

  EXPECT_FALSE(
      fake_browser()->BootstrapMojoConnection(&fake_mojo_fd_generator));

  Mock::VerifyAndClearExpectations(core_delegate());
}

// Test that second attempt to bootstrap the Mojo service results in error and
// the daemon shutdown.
TEST_F(DiagnosticsdCoreTest, MojoBootstrapErrorRepeated) {
  FakeMojoFdGenerator first_fake_mojo_fd_generator;
  SetSuccessMockBindDiagnosticsdMojoService(&first_fake_mojo_fd_generator);

  EXPECT_TRUE(
      fake_browser()->BootstrapMojoConnection(&first_fake_mojo_fd_generator));
  Mock::VerifyAndClearExpectations(core_delegate());

  FakeMojoFdGenerator second_fake_mojo_fd_generator;
  EXPECT_CALL(*core_delegate(), BeginDaemonShutdown());

  EXPECT_FALSE(
      fake_browser()->BootstrapMojoConnection(&second_fake_mojo_fd_generator));

  Mock::VerifyAndClearExpectations(core_delegate());
}

// Test that the daemon gets shut down when the previously bootstrapped Mojo
// connection aborts.
TEST_F(DiagnosticsdCoreTest, MojoBootstrapSuccessThenAbort) {
  FakeMojoFdGenerator fake_mojo_fd_generator;
  SetSuccessMockBindDiagnosticsdMojoService(&fake_mojo_fd_generator);

  EXPECT_TRUE(fake_browser()->BootstrapMojoConnection(&fake_mojo_fd_generator));

  Mock::VerifyAndClearExpectations(core_delegate());

  EXPECT_CALL(*core_delegate(), BeginDaemonShutdown());

  // Abort the Mojo connection by closing the browser-side endpoint.
  mojo_service_factory_interface_ptr()->reset();
  base::RunLoop().RunUntilIdle();
  Mock::VerifyAndClearExpectations(core_delegate());
}

namespace {

// Tests for the DiagnosticsdCore class with the already established Mojo
// connection to the fake browser and gRPC communication with the fake
// diagnostics_processor.
class BootstrappedDiagnosticsdCoreTest : public DiagnosticsdCoreTest {
 protected:
  void SetUp() override {
    ASSERT_NO_FATAL_FAILURE(DiagnosticsdCoreTest::SetUp());

    FakeMojoFdGenerator fake_mojo_fd_generator;
    SetSuccessMockBindDiagnosticsdMojoService(&fake_mojo_fd_generator);
    ASSERT_TRUE(
        fake_browser()->BootstrapMojoConnection(&fake_mojo_fd_generator));
    ASSERT_TRUE(*mojo_service_factory_interface_ptr());

    fake_diagnostics_processor_ = std::make_unique<FakeDiagnosticsProcessor>(
        diagnostics_processor_grpc_uri(), diagnosticsd_grpc_uri());

    fake_ui_message_receiver_diagnostics_processor_ =
        std::make_unique<FakeDiagnosticsProcessor>(
            ui_message_receiver_diagnostics_processor_grpc_uri(),
            diagnosticsd_grpc_uri());
  }

  void TearDown() override {
    fake_diagnostics_processor_.reset();
    fake_ui_message_receiver_diagnostics_processor_.reset();
    DiagnosticsdCoreTest::TearDown();
  }

  FakeDiagnosticsProcessor* fake_ui_message_receiver_diagnostics_processor() {
    return fake_ui_message_receiver_diagnostics_processor_.get();
  }

  FakeDiagnosticsProcessor* fake_diagnostics_processor() {
    return fake_diagnostics_processor_.get();
  }

  base::Callback<void(mojo::ScopedHandle)> fake_browser_valid_handle_callback(
      const base::Closure& callback,
      const std::string& expected_response_json_message) {
    return base::Bind(
        [](const base::Closure& callback,
           const std::string& expected_response_json_message,
           mojo::ScopedHandle response_json_message_handle) {
          std::unique_ptr<base::SharedMemory> shared_memory =
              GetReadOnlySharedMemoryFromMojoHandle(
                  std::move(response_json_message_handle));
          ASSERT_TRUE(shared_memory);
          ASSERT_EQ(
              expected_response_json_message,
              std::string(static_cast<const char*>(shared_memory->memory()),
                          shared_memory->mapped_size()));
          callback.Run();
        },
        callback, expected_response_json_message);
  }

  base::Callback<void(mojo::ScopedHandle)> fake_browser_invalid_handle_callback(
      const base::Closure& callback) {
    return base::Bind(
        [](const base::Closure& callback,
           mojo::ScopedHandle response_json_message_handle) {
          ASSERT_FALSE(response_json_message_handle.is_valid());
          callback.Run();
        },
        callback);
  }

 private:
  std::unique_ptr<FakeDiagnosticsProcessor>
      fake_ui_message_receiver_diagnostics_processor_;
  std::unique_ptr<FakeDiagnosticsProcessor> fake_diagnostics_processor_;
};

}  // namespace

// Test that the UI message receiver diagnostics processor will receive message
// from browser.
TEST_F(BootstrappedDiagnosticsdCoreTest,
       SendGrpcUiMessageToDiagnosticsProcessor) {
  const std::string json_message = "{\"some_key\": \"some_value\"}";
  const std::string response_json_message = "{\"key\": \"value\"}";

  base::RunLoop run_loop_diagnostics_processor;
  base::RunLoop run_loop_fake_browser;

  fake_ui_message_receiver_diagnostics_processor()
      ->set_handle_message_from_ui_callback(
          run_loop_diagnostics_processor.QuitClosure());
  fake_ui_message_receiver_diagnostics_processor()
      ->set_handle_message_from_ui_json_message_response(response_json_message);
  fake_diagnostics_processor()->set_handle_message_from_ui_callback(
      base::Bind([]() {
        // The diagnostics processor not eligible to receive messages from UI
        // must not receive them.
        FAIL();
      }));

  auto callback = fake_browser_valid_handle_callback(
      run_loop_fake_browser.QuitClosure(), response_json_message);
  EXPECT_TRUE(fake_browser()->SendUiMessageToDiagnosticsProcessor(json_message,
                                                                  callback));

  run_loop_diagnostics_processor.Run();
  run_loop_fake_browser.Run();
  EXPECT_EQ(json_message, fake_ui_message_receiver_diagnostics_processor()
                              ->handle_message_from_ui_actual_json_message());
}

// Test that the UI message receiver diagnostics processor will not receive
// message from browser if JSON message is invalid.
TEST_F(BootstrappedDiagnosticsdCoreTest,
       SendGrpcUiMessageToDiagnosticsProcessorInvalidJSON) {
  const std::string json_message = "{'some_key': 'some_value'}";

  base::RunLoop run_loop_fake_browser;

  auto callback =
      fake_browser_invalid_handle_callback(run_loop_fake_browser.QuitClosure());
  EXPECT_TRUE(fake_browser()->SendUiMessageToDiagnosticsProcessor(json_message,
                                                                  callback));

  run_loop_fake_browser.Run();
  // There's no reliable way to wait till the wrong HandleMessageFromUi(), if
  // the tested code is buggy and calls it, gets executed. The RunUntilIdle() is
  // used to make the test failing at least with some probability in case of
  // such a bug.
  base::RunLoop().RunUntilIdle();

  EXPECT_FALSE(fake_ui_message_receiver_diagnostics_processor()
                   ->handle_message_from_ui_actual_json_message()
                   .has_value());
}

// Test that the UI message receiver diagnostics processor will receive message
// from browser.
TEST_F(BootstrappedDiagnosticsdCoreTest,
       SendGrpcUiMessageToDiagnosticsProcessorInvalidResponseJSON) {
  const std::string json_message = "{\"some_key\": \"some_value\"}";
  const std::string response_json_message = "{'key': 'value'}";

  base::RunLoop run_loop_diagnostics_processor;
  base::RunLoop run_loop_fake_browser;

  fake_ui_message_receiver_diagnostics_processor()
      ->set_handle_message_from_ui_callback(
          run_loop_diagnostics_processor.QuitClosure());
  fake_ui_message_receiver_diagnostics_processor()
      ->set_handle_message_from_ui_json_message_response(response_json_message);

  auto callback =
      fake_browser_invalid_handle_callback(run_loop_fake_browser.QuitClosure());
  EXPECT_TRUE(fake_browser()->SendUiMessageToDiagnosticsProcessor(json_message,
                                                                  callback));

  run_loop_diagnostics_processor.Run();
  run_loop_fake_browser.Run();
  EXPECT_EQ(json_message, fake_ui_message_receiver_diagnostics_processor()
                              ->handle_message_from_ui_actual_json_message());
}

// Test that the GetProcData() method exposed by the daemon's gRPC server
// returns a dump of the corresponding file from the disk.
TEST_F(BootstrappedDiagnosticsdCoreTest, GetProcDataGrpcCall) {
  const std::string kFakeFileContents = "foo";
  const base::FilePath file_path = temp_dir_path().Append("proc/uptime");
  ASSERT_TRUE(WriteFileAndCreateParentDirs(file_path, kFakeFileContents));

  grpc_api::GetProcDataRequest request;
  request.set_type(grpc_api::GetProcDataRequest::FILE_UPTIME);
  std::unique_ptr<grpc_api::GetProcDataResponse> response;
  base::RunLoop run_loop;
  fake_diagnostics_processor()->GetProcData(
      request, MakeAsyncResponseWriter(&response, &run_loop));
  run_loop.Run();

  ASSERT_TRUE(response);
  grpc_api::GetProcDataResponse expected_response;
  expected_response.add_file_dump();
  expected_response.mutable_file_dump(0)->set_path(file_path.value());
  expected_response.mutable_file_dump(0)->set_canonical_path(file_path.value());
  expected_response.mutable_file_dump(0)->set_contents(kFakeFileContents);
  EXPECT_TRUE(google::protobuf::util::MessageDifferencer::Equals(
      *response, expected_response))
      << "Obtained: " << response->ShortDebugString()
      << ",\nExpected: " << expected_response.ShortDebugString();
}

// Test that the RunEcCommand() method exposed by the daemon's gRPC server
// writes payload to sysfs file exposed by the EC driver and reads response
// using the same file.
TEST_F(BootstrappedDiagnosticsdCoreTest, RunEcCommandGrpcCall) {
  const base::FilePath file_path =
      temp_dir_path().Append(kEcDriverSysfsPath).Append(kEcRunCommandFilePath);
  const std::string kRequestPayload = "1";
  ASSERT_TRUE(WriteFileAndCreateParentDirs(file_path, ""));

  grpc_api::RunEcCommandRequest request;
  request.set_payload(kRequestPayload);
  std::unique_ptr<grpc_api::RunEcCommandResponse> response;
  base::RunLoop run_loop;
  fake_diagnostics_processor()->RunEcCommand(
      request, MakeAsyncResponseWriter(&response, &run_loop));
  run_loop.Run();

  ASSERT_TRUE(response);
  grpc_api::RunEcCommandResponse expected_response;
  expected_response.set_status(grpc_api::RunEcCommandResponse::STATUS_OK);
  expected_response.set_payload(kRequestPayload);
  EXPECT_THAT(*response, ProtobufEquals(expected_response))
      << "Actual: {" << response->ShortDebugString() << "}";
}

// Test that the GetEcProperty() method exposed by the daemon's gRPC server
// returns a dump of the corresponding file from the disk.
TEST_F(BootstrappedDiagnosticsdCoreTest, GetEcPropertyGrpcCall) {
  const base::FilePath file_path = temp_dir_path()
                                       .Append(kEcDriverSysfsPath)
                                       .Append(kEcDriverSysfsPropertiesPath)
                                       .Append(kEcPropertyGlobalMicMuteLed);
  const std::string kFakeFileContents = "1";
  ASSERT_TRUE(WriteFileAndCreateParentDirs(file_path, kFakeFileContents));

  grpc_api::GetEcPropertyRequest request;
  request.set_property(
      grpc_api::GetEcPropertyRequest::PROPERTY_GLOBAL_MIC_MUTE_LED);
  std::unique_ptr<grpc_api::GetEcPropertyResponse> response;
  base::RunLoop run_loop;
  fake_diagnostics_processor()->GetEcProperty(
      request, MakeAsyncResponseWriter(&response, &run_loop));
  run_loop.Run();

  ASSERT_TRUE(response);
  grpc_api::GetEcPropertyResponse expected_response;
  expected_response.set_status(grpc_api::GetEcPropertyResponse::STATUS_OK);
  expected_response.set_payload(kFakeFileContents);
  EXPECT_THAT(*response, ProtobufEquals(expected_response))
      << "Actual: {" << response->ShortDebugString() << "}";
}

// Test that PerformWebRequest() method exposed by the daemon's gRPC returns a
// Web request response from the browser.
TEST_F(BootstrappedDiagnosticsdCoreTest, PerformWebRequestToBrowser) {
  constexpr char kHttpsUrl[] = "https://www.google.com";
  constexpr int kHttpStatusOk = 200;

  grpc_api::PerformWebRequestParameter request;
  request.set_http_method(
      grpc_api::PerformWebRequestParameter::HTTP_METHOD_GET);
  request.set_url(kHttpsUrl);

  std::unique_ptr<grpc_api::PerformWebRequestResponse> response;
  {
    base::RunLoop run_loop;
    fake_diagnostics_processor()->PerformWebRequest(
        request, MakeAsyncResponseWriter(&response, &run_loop));
    run_loop.Run();
  }

  ASSERT_TRUE(response);
  grpc_api::PerformWebRequestResponse expected_response;
  expected_response.set_status(grpc_api::PerformWebRequestResponse::STATUS_OK);
  expected_response.set_http_status(kHttpStatusOk);
  EXPECT_THAT(*response, ProtobufEquals(expected_response))
      << "Actual: {" << response->ShortDebugString() << "}";
}

namespace {

// Fake types to be used to emulate EC events.
const uint16_t kFakeEcEventType1 = 0xabcd;
const uint16_t kFakeEcEventType2 = 0x1234;

// Tests for EC event service.
class EcEventServiceBootstrappedDiagnosticsdCoreTest
    : public BootstrappedDiagnosticsdCoreTest {
 protected:
  void EmulateEcEvent(uint16_t size, uint16_t type) const {
    WriteEcEventToSysfsFile(GetEcEvent(size, type));
  }

  void ExpectFakeProcessorEcEventCalled(
      FakeDiagnosticsProcessor* fake_diagnostics_processor,
      uint16_t expected_size,
      uint16_t type) {
    const std::string payload = GetPayload(
        expected_size * sizeof(DiagnosticsdEcEventService::EcEvent::data[0]));
    base::RunLoop run_loop;
    fake_diagnostics_processor->set_handle_ec_event_request_callback(
        base::BindRepeating(
            [](const base::Closure& callback, int32_t expected_type,
               const std::string& expected_payload, int32_t type,
               const std::string& payload) {
              ASSERT_EQ(type, expected_type);
              ASSERT_EQ(payload, expected_payload);
              callback.Run();
            },
            run_loop.QuitClosure(), type, payload));
    run_loop.Run();
  }

 private:
  const uint16_t kData[6]{0x0102, 0x1314, 0x2526, 0x3738, 0x494a, 0x5b5c};
  // |kData| bytes little endian representation.
  const uint8_t kPayload[12]{0x02, 0x01, 0x14, 0x13, 0x26, 0x25,
                             0x38, 0x37, 0x4a, 0x49, 0x5c, 0x5b};

  DiagnosticsdEcEventService::EcEvent GetEcEvent(uint16_t size,
                                                 uint16_t type) const {
    return DiagnosticsdEcEventService::EcEvent(size, type, kData);
  }

  std::string GetPayload(size_t expected_size_in_bytes) const {
    return std::string(reinterpret_cast<const char*>(kPayload),
                       expected_size_in_bytes);
  }
};

}  // namespace

// Test that the method |HandleEcNotification()| exposed by diagnostics
// processor gRPC is called by diagnostics deamon.
// TODO(b/124598866): Disabled due to flakiness.
TEST_F(EcEventServiceBootstrappedDiagnosticsdCoreTest,
       DISABLED_SendGrpcEcEventToDiagnosticsProcessorSize0) {
  EmulateEcEvent(0, kFakeEcEventType1);
  ExpectFakeProcessorEcEventCalled(fake_diagnostics_processor(), 0,
                                   kFakeEcEventType1);
  ExpectFakeProcessorEcEventCalled(
      fake_ui_message_receiver_diagnostics_processor(), 0, kFakeEcEventType1);
}

// TODO(b/124598866): Disabled due to flakiness.
TEST_F(EcEventServiceBootstrappedDiagnosticsdCoreTest,
       DISABLED_SendGrpcEcEventToDiagnosticsProcessorSize5) {
  EmulateEcEvent(5, kFakeEcEventType1);
  ExpectFakeProcessorEcEventCalled(fake_diagnostics_processor(), 5,
                                   kFakeEcEventType1);
  ExpectFakeProcessorEcEventCalled(
      fake_ui_message_receiver_diagnostics_processor(), 5, kFakeEcEventType1);
}

// TODO(b/124598866): Disabled due to flakiness.
TEST_F(EcEventServiceBootstrappedDiagnosticsdCoreTest,
       DISABLED_SendGrpcEcEventToDiagnosticsProcessorSize6) {
  EmulateEcEvent(6, kFakeEcEventType1);
  ExpectFakeProcessorEcEventCalled(fake_diagnostics_processor(), 6,
                                   kFakeEcEventType1);
  ExpectFakeProcessorEcEventCalled(
      fake_ui_message_receiver_diagnostics_processor(), 6, kFakeEcEventType1);
}

// Test that the method |HandleEcNotification()| exposed by diagnostics
// processor gRPC is called by diagnostics deamon multiple times.
// TODO(b/124598866): Disabled due to flakiness.
TEST_F(EcEventServiceBootstrappedDiagnosticsdCoreTest,
       DISABLED_SendGrpcEcEventToDiagnosticsProcessorMultipleEvents) {
  EmulateEcEvent(3, kFakeEcEventType1);
  EmulateEcEvent(4, kFakeEcEventType2);
  ExpectFakeProcessorEcEventCalled(fake_diagnostics_processor(), 3,
                                   kFakeEcEventType1);
  ExpectFakeProcessorEcEventCalled(fake_diagnostics_processor(), 4,
                                   kFakeEcEventType2);
  ExpectFakeProcessorEcEventCalled(
      fake_ui_message_receiver_diagnostics_processor(), 3, kFakeEcEventType1);
  ExpectFakeProcessorEcEventCalled(
      fake_ui_message_receiver_diagnostics_processor(), 4, kFakeEcEventType2);
}

// Test that the method |HandleEcNotification()| exposed by diagnostics
// processor gRPC is called by diagnostics deamon even when |ec_event.size|
// exceeds allocated data array.
// TODO(b/124598866): Disabled due to flakiness.
TEST_F(EcEventServiceBootstrappedDiagnosticsdCoreTest,
       DISABLED_SendGrpcEcEventToDiagnosticsProcessorInvalidSize) {
  EmulateEcEvent(7, kFakeEcEventType1);
  ExpectFakeProcessorEcEventCalled(fake_diagnostics_processor(), 6,
                                   kFakeEcEventType1);
  ExpectFakeProcessorEcEventCalled(
      fake_ui_message_receiver_diagnostics_processor(), 6, kFakeEcEventType1);
}

}  // namespace diagnostics
