// 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 <cstdint>
#include <iterator>
#include <memory>
#include <string>
#include <tuple>
#include <utility>
#include <vector>

#include <base/bind.h>
#include <base/callback.h>
#include <base/files/file_path.h>
#include <base/files/scoped_temp_dir.h>
#include <base/optional.h>
#include <base/run_loop.h>
#include <base/strings/string_piece.h>
#include <base/strings/stringprintf.h>
#include <base/system/sys_info.h>
#include <base/test/task_environment.h>
#include <base/time/time.h>
#include <gmock/gmock.h>
#include <google/protobuf/repeated_field.h>
#include <gtest/gtest.h>

#include "diagnostics/common/file_test_utils.h"
#include "diagnostics/common/protobuf_test_utils.h"
#include "diagnostics/wilco_dtc_supportd/ec_constants.h"
#include "diagnostics/wilco_dtc_supportd/grpc_service.h"
#include "diagnostics/wilco_dtc_supportd/telemetry/mock_system_files_service.h"
#include "diagnostics/wilco_dtc_supportd/telemetry/mock_system_info_service.h"

#include "mojo/cros_healthd_probe.mojom.h"
#include "wilco_dtc_supportd.pb.h"  // NOLINT(build/include)

using testing::_;
using testing::AnyOf;
using testing::ByMove;
using testing::ByRef;
using testing::DoAll;
using testing::Eq;
using testing::Invoke;
using testing::NotNull;
using testing::Return;
using testing::SetArgPointee;
using testing::StrEq;
using testing::StrictMock;
using testing::UnorderedElementsAre;
using testing::WithArgs;

namespace diagnostics {

namespace {

using DelegateWebRequestHttpMethod =
    GrpcService::Delegate::WebRequestHttpMethod;
using DelegateWebRequestStatus = GrpcService::Delegate::WebRequestStatus;
using DelegateDriveSystemDataType = GrpcService::Delegate::DriveSystemDataType;

constexpr char kFakeFileContentsChars[] = "\0fake Æ row 1\nfake row 2\n\0\377";

constexpr int kHttpStatusOk = 200;
constexpr char kBadNonHttpsUrl[] = "Http://www.google.com";
constexpr char kCorrectUrl[] = "hTTps://www.google.com";
constexpr char kFakeWebResponseBody[] = "\0Fake WEB\n response body\n\0";
const DelegateWebRequestHttpMethod kDelegateWebRequestHttpMethodGet =
    DelegateWebRequestHttpMethod::kGet;
const DelegateWebRequestHttpMethod kDelegateWebRequestHttpMethodHead =
    DelegateWebRequestHttpMethod::kHead;
const DelegateWebRequestHttpMethod kDelegateWebRequestHttpMethodPost =
    DelegateWebRequestHttpMethod::kPost;
const DelegateWebRequestHttpMethod kDelegateWebRequestHttpMethodPut =
    DelegateWebRequestHttpMethod::kPut;
const DelegateWebRequestHttpMethod kDelegateWebRequestHttpMethodPatch =
    DelegateWebRequestHttpMethod::kPatch;

constexpr grpc_api::DiagnosticRoutine kFakeAvailableRoutines[] = {
    grpc_api::ROUTINE_BATTERY,
    grpc_api::ROUTINE_BATTERY_SYSFS,
    grpc_api::ROUTINE_SMARTCTL_CHECK,
    grpc_api::ROUTINE_URANDOM,
    grpc_api::ROUTINE_FLOATING_POINT_ACCURACY,
    grpc_api::ROUTINE_NVME_SHORT_SELF_TEST,
    grpc_api::ROUTINE_NVME_LONG_SELF_TEST};
constexpr int kFakeUuid = 13;
constexpr grpc_api::DiagnosticRoutineStatus kFakeStatus =
    grpc_api::ROUTINE_STATUS_RUNNING;
constexpr int kFakeProgressPercent = 37;
constexpr grpc_api::DiagnosticRoutineUserMessage kFakeUserMessage =
    grpc_api::ROUTINE_USER_MESSAGE_UNSET;
constexpr char kFakeOutput[] = "Some output.";
constexpr char kFakeStatusMessage[] = "Status message.";

constexpr char kTestFilePath[] = "file/path";
constexpr char kTestCanonicalFilePath[] = "canonical/path";

std::string FakeFileContents() {
  return std::string(std::begin(kFakeFileContentsChars),
                     std::end(kFakeFileContentsChars));
}

template <class T>
base::Callback<void(grpc::Status, std::unique_ptr<T>)>
GrpcCallbackResponseSaver(std::unique_ptr<T>* response) {
  return base::Bind(
      [](std::unique_ptr<T>* response, grpc::Status status,
         std::unique_ptr<T> received_response) {
        *response = std::move(received_response);
        ASSERT_TRUE(*response);
      },
      base::Unretained(response));
}

std::unique_ptr<grpc_api::GetEcTelemetryResponse> MakeGetEcTelemetryResponse(
    grpc_api::GetEcTelemetryResponse::Status status,
    const std::string& payload) {
  auto response = std::make_unique<grpc_api::GetEcTelemetryResponse>();
  response->set_status(status);
  response->set_payload(payload);
  return response;
}

std::unique_ptr<grpc_api::PerformWebRequestResponse>
MakePerformWebRequestResponse(
    grpc_api::PerformWebRequestResponse::Status status,
    const int* http_status,
    const char* response_body) {
  auto response = std::make_unique<grpc_api::PerformWebRequestResponse>();
  response->set_status(status);
  if (http_status)
    response->set_http_status(*http_status);
  if (response_body)
    response->set_response_body(response_body);
  return response;
}

std::unique_ptr<grpc_api::GetAvailableRoutinesResponse>
MakeGetAvailableRoutinesResponse() {
  auto response = std::make_unique<grpc_api::GetAvailableRoutinesResponse>();
  for (auto routine : kFakeAvailableRoutines)
    response->add_routines(routine);
  response->set_service_status(grpc_api::ROUTINE_SERVICE_STATUS_OK);
  return response;
}

std::unique_ptr<grpc_api::RunRoutineResponse> MakeRunRoutineResponse() {
  auto response = std::make_unique<grpc_api::RunRoutineResponse>();
  response->set_uuid(kFakeUuid);
  response->set_status(kFakeStatus);
  response->set_service_status(grpc_api::ROUTINE_SERVICE_STATUS_OK);
  return response;
}

std::unique_ptr<grpc_api::GetRoutineUpdateResponse>
MakeGetRoutineUpdateResponse(int uuid, bool include_output) {
  auto response = std::make_unique<grpc_api::GetRoutineUpdateResponse>();
  response->set_uuid(uuid);
  response->set_status(kFakeStatus);
  response->set_progress_percent(kFakeProgressPercent);
  response->set_user_message(kFakeUserMessage);
  response->set_output(include_output ? kFakeOutput : "");
  response->set_status_message(kFakeStatusMessage);
  response->set_service_status(grpc_api::ROUTINE_SERVICE_STATUS_OK);
  return response;
}

std::unique_ptr<grpc_api::RunRoutineRequest> MakeRunBatteryRoutineRequest() {
  constexpr int kLowmAh = 10;
  constexpr int kHighmAh = 100;
  auto request = std::make_unique<grpc_api::RunRoutineRequest>();
  request->set_routine(grpc_api::ROUTINE_BATTERY);
  request->mutable_battery_params()->set_low_mah(kLowmAh);
  request->mutable_battery_params()->set_high_mah(kHighmAh);
  return request;
}

std::unique_ptr<grpc_api::RunRoutineRequest>
MakeRunBatterySysfsRoutineRequest() {
  constexpr int kMaximumCycleCount = 5;
  constexpr int kPercentBatteryWearAllowed = 10;
  auto request = std::make_unique<grpc_api::RunRoutineRequest>();
  request->set_routine(grpc_api::ROUTINE_BATTERY_SYSFS);
  request->mutable_battery_sysfs_params()->set_maximum_cycle_count(
      kMaximumCycleCount);
  request->mutable_battery_sysfs_params()->set_percent_battery_wear_allowed(
      kPercentBatteryWearAllowed);
  return request;
}

std::unique_ptr<grpc_api::RunRoutineRequest> MakeRunUrandomRoutineRequest() {
  constexpr int kLengthSeconds = 10;
  auto request = std::make_unique<grpc_api::RunRoutineRequest>();
  request->set_routine(grpc_api::ROUTINE_URANDOM);
  request->mutable_urandom_params()->set_length_seconds(kLengthSeconds);
  return request;
}

std::unique_ptr<grpc_api::RunRoutineRequest>
MakeRunFloatingPointAccuracyRoutineRequest() {
  constexpr int kLengthSeconds = 10;
  auto request = std::make_unique<grpc_api::RunRoutineRequest>();
  request->set_routine(grpc_api::ROUTINE_FLOATING_POINT_ACCURACY);
  request->mutable_floating_point_accuracy_params()->set_length_seconds(
      kLengthSeconds);
  return request;
}

std::unique_ptr<grpc_api::RunRoutineRequest>
MakeRunNvmeWearLevelRoutineRequest() {
  constexpr int kWearLevelThreshold = 50;
  auto request = std::make_unique<grpc_api::RunRoutineRequest>();
  request->set_routine(grpc_api::ROUTINE_NVME_WEAR_LEVEL);
  request->mutable_nvme_wear_level_params()->set_wear_level_threshold(
      kWearLevelThreshold);
  return request;
}

std::unique_ptr<grpc_api::RunRoutineRequest>
MakeRunNvmeShortSelfTestRoutineRequest() {
  auto request = std::make_unique<grpc_api::RunRoutineRequest>();
  request->set_routine(grpc_api::ROUTINE_NVME_SHORT_SELF_TEST);
  request->mutable_nvme_short_self_test_params();
  return request;
}

std::unique_ptr<grpc_api::RunRoutineRequest>
MakeRunNvmeLongSelfTestRoutineRequest() {
  auto request = std::make_unique<grpc_api::RunRoutineRequest>();
  request->set_routine(grpc_api::ROUTINE_NVME_LONG_SELF_TEST);
  request->mutable_nvme_long_self_test_params();
  return request;
}

std::unique_ptr<grpc_api::RunRoutineRequest>
MakeRunPrimeSearchRoutineRequest() {
  constexpr int kLengthSeconds = 10;
  constexpr int kMaxNum = 1000000;
  auto request = std::make_unique<grpc_api::RunRoutineRequest>();
  request->set_routine(grpc_api::ROUTINE_PRIME_SEARCH);
  request->mutable_prime_search_params()->set_length_seconds(kLengthSeconds);
  request->mutable_prime_search_params()->set_max_num(kMaxNum);
  return request;
}

MATCHER_P(GrpcDumpsEquivalentWithInternal, expected, "") {
  if (arg.size() != expected.get().size())
    return false;

  for (int i = 0; i < arg.size(); i++) {
    if (arg[i].contents() != expected.get()[i]->contents ||
        arg[i].canonical_path() != expected.get()[i]->canonical_path.value() ||
        arg[i].path() != expected.get()[i]->path.value())
      return false;
  }

  return true;
}

class MockGrpcServiceDelegate : public GrpcService::Delegate {
 public:
  // GrpcService::Delegate overrides:
  MOCK_METHOD(void,
              SendWilcoDtcMessageToUi,
              (const std::string&, const SendMessageToUiCallback&),
              (override));
  MOCK_METHOD(void,
              PerformWebRequestToBrowser,
              (WebRequestHttpMethod,
               const std::string&,
               const std::vector<std::string>&,
               const std::string&,
               const PerformWebRequestToBrowserCallback&),
              (override));
  MOCK_METHOD(void,
              GetAvailableRoutinesToService,
              (const GetAvailableRoutinesToServiceCallback&),
              (override));
  MOCK_METHOD(void,
              RunRoutineToService,
              (const grpc_api::RunRoutineRequest&,
               const RunRoutineToServiceCallback&),
              (override));
  MOCK_METHOD(void,
              GetRoutineUpdateRequestToService,
              (const int,
               const grpc_api::GetRoutineUpdateRequest::Command,
               const bool,
               const GetRoutineUpdateRequestToServiceCallback&),
              (override));
  MOCK_METHOD(void,
              GetConfigurationDataFromBrowser,
              (const GetConfigurationDataFromBrowserCallback&),
              (override));
  MOCK_METHOD(void,
              GetDriveSystemData,
              (DriveSystemDataType, const GetDriveSystemDataCallback&),
              (override));
  MOCK_METHOD(void, RequestBluetoothDataNotification, (), (override));
  MOCK_METHOD(
      void,
      ProbeTelemetryInfo,
      (std::vector<chromeos::cros_healthd::mojom::ProbeCategoryEnum> categories,
       ProbeTelemetryInfoCallback callback),
      (override));
  EcService* GetEcService() override { return ec_service_.get(); }

 private:
  std::unique_ptr<EcService> ec_service_ = std::make_unique<EcService>();
};

// Tests for the GrpcService class.
class GrpcServiceTest : public testing::Test {
 protected:
  GrpcServiceTest() = default;

  void SetUp() override {
    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
    service_.set_root_dir_for_testing(temp_dir_.GetPath());
    delegate_.GetEcService()->set_root_dir_for_testing(temp_dir_.GetPath());
  }

  GrpcService* service() { return &service_; }

  StrictMock<MockGrpcServiceDelegate>* delegate() { return &delegate_; }

  void ExecuteSendMessageToUi(
      const std::string& json_message,
      std::unique_ptr<grpc_api::SendMessageToUiResponse>* response) {
    auto request = std::make_unique<grpc_api::SendMessageToUiRequest>();
    request->set_json_message(json_message);
    EXPECT_CALL(delegate_, SendWilcoDtcMessageToUi(json_message, _))
        .WillOnce(WithArgs<1>(Invoke(
            [json_message](const base::Callback<void(
                               grpc::Status, base::StringPiece)>& callback) {
              callback.Run(grpc::Status::OK, json_message);
            })));
    service()->SendMessageToUi(std::move(request),
                               GrpcCallbackResponseSaver(response));
  }

  void ExecuteGetProcData(grpc_api::GetProcDataRequest::Type request_type,
                          std::vector<grpc_api::FileDump>* file_dumps) {
    auto request = std::make_unique<grpc_api::GetProcDataRequest>();
    request->set_type(request_type);
    std::unique_ptr<grpc_api::GetProcDataResponse> response;
    service()->GetProcData(std::move(request),
                           GrpcCallbackResponseSaver(&response));

    // Expect the method to return immediately.
    ASSERT_TRUE(response);
    file_dumps->assign(response->file_dump().begin(),
                       response->file_dump().end());
  }

  void ExecuteGetSysfsData(grpc_api::GetSysfsDataRequest::Type request_type,
                           std::vector<grpc_api::FileDump>* file_dumps) {
    auto request = std::make_unique<grpc_api::GetSysfsDataRequest>();
    request->set_type(request_type);
    std::unique_ptr<grpc_api::GetSysfsDataResponse> response;
    service()->GetSysfsData(std::move(request),
                            GrpcCallbackResponseSaver(&response));

    // Expect the method to return immediately.
    ASSERT_TRUE(response);
    file_dumps->assign(response->file_dump().begin(),
                       response->file_dump().end());
  }

  void ExecuteGetEcTelemetry(
      const std::string request_payload,
      std::unique_ptr<grpc_api::GetEcTelemetryResponse>* response) {
    auto request = std::make_unique<grpc_api::GetEcTelemetryRequest>();
    request->set_payload(request_payload);

    service()->GetEcTelemetry(std::move(request),
                              GrpcCallbackResponseSaver(response));
    ASSERT_TRUE(*response);
  }

  void ExecutePerformWebRequest(
      grpc_api::PerformWebRequestParameter::HttpMethod http_method,
      const std::string& url,
      const std::vector<std::string>& string_headers,
      const std::string& request_body,
      const DelegateWebRequestHttpMethod* delegate_http_method,
      std::unique_ptr<grpc_api::PerformWebRequestResponse>* response) {
    auto request = std::make_unique<grpc_api::PerformWebRequestParameter>();
    request->set_http_method(http_method);
    request->set_url(url);

    google::protobuf::RepeatedPtrField<std::string> headers(
        string_headers.begin(), string_headers.end());
    request->mutable_headers()->Swap(&headers);

    request->set_request_body(request_body);

    base::Callback<void(DelegateWebRequestStatus, int)> callback;
    if (delegate_http_method) {
      EXPECT_CALL(delegate_,
                  PerformWebRequestToBrowser(Eq(*delegate_http_method), url,
                                             string_headers, request_body, _))
          .WillOnce(WithArgs<4>(Invoke(
              [](const base::Callback<void(DelegateWebRequestStatus, int,
                                           base::StringPiece)>& callback) {
                callback.Run(DelegateWebRequestStatus::kOk, kHttpStatusOk,
                             kFakeWebResponseBody);
              })));
    }
    service()->PerformWebRequest(std::move(request),
                                 GrpcCallbackResponseSaver(response));
  }

  void ExecuteGetAvailableRoutines(
      std::unique_ptr<grpc_api::GetAvailableRoutinesResponse>* response) {
    auto request = std::make_unique<grpc_api::GetAvailableRoutinesRequest>();
    EXPECT_CALL(delegate_, GetAvailableRoutinesToService(_))
        .WillOnce(Invoke([](const base::Callback<void(
                                const std::vector<grpc_api::DiagnosticRoutine>&,
                                grpc_api::RoutineServiceStatus)>& callback) {
          callback.Run(std::vector<grpc_api::DiagnosticRoutine>(
                           std::begin(kFakeAvailableRoutines),
                           std::end(kFakeAvailableRoutines)),
                       grpc_api::ROUTINE_SERVICE_STATUS_OK);
        }));
    service()->GetAvailableRoutines(std::move(request),
                                    GrpcCallbackResponseSaver(response));
  }

  void ExecuteRunRoutine(
      std::unique_ptr<grpc_api::RunRoutineRequest> request,
      std::unique_ptr<grpc_api::RunRoutineResponse>* response,
      bool is_valid_request) {
    if (is_valid_request) {
      EXPECT_CALL(delegate_, RunRoutineToService(_, _))
          .WillOnce(WithArgs<1>(
              Invoke([](const base::Callback<void(
                            int, grpc_api::DiagnosticRoutineStatus,
                            grpc_api::RoutineServiceStatus)>& callback) {
                callback.Run(kFakeUuid, kFakeStatus,
                             grpc_api::ROUTINE_SERVICE_STATUS_OK);
              })));
    }
    service()->RunRoutine(std::move(request),
                          GrpcCallbackResponseSaver(response));
  }

  void ExecuteGetRoutineUpdate(
      int uuid,
      grpc_api::GetRoutineUpdateRequest::Command command,
      bool include_output,
      std::unique_ptr<grpc_api::GetRoutineUpdateResponse>* response) {
    if (command != grpc_api::GetRoutineUpdateRequest::COMMAND_UNSET) {
      EXPECT_CALL(delegate_, GetRoutineUpdateRequestToService(
                                 uuid, command, include_output, _))
          .WillOnce(WithArgs<3>(
              Invoke([=](const base::Callback<void(
                             int, grpc_api::DiagnosticRoutineStatus, int,
                             grpc_api::DiagnosticRoutineUserMessage,
                             const std::string&, const std::string&,
                             grpc_api::RoutineServiceStatus)>& callback) {
                callback.Run(
                    uuid, kFakeStatus, kFakeProgressPercent, kFakeUserMessage,
                    include_output ? kFakeOutput : "", kFakeStatusMessage,
                    grpc_api::ROUTINE_SERVICE_STATUS_OK);
              })));
    }
    auto request = std::make_unique<grpc_api::GetRoutineUpdateRequest>();
    request->set_uuid(uuid);
    request->set_command(command);
    request->set_include_output(include_output);
    service()->GetRoutineUpdate(std::move(request),
                                GrpcCallbackResponseSaver(response));
  }

  void ExecuteGetConfigurationData(
      const std::string& json_configuration_data,
      std::unique_ptr<grpc_api::GetConfigurationDataResponse>* response) {
    auto request = std::make_unique<grpc_api::GetConfigurationDataRequest>();
    EXPECT_CALL(delegate_, GetConfigurationDataFromBrowser(_))
        .WillOnce(WithArgs<0>(Invoke(
            [json_configuration_data](
                const base::Callback<void(const std::string&)>& callback) {
              callback.Run(json_configuration_data);
            })));
    service()->GetConfigurationData(std::move(request),
                                    GrpcCallbackResponseSaver(response));
  }

  void ExecuteGetVpdField(grpc_api::GetVpdFieldRequest::VpdField vpd_field,
                          grpc_api::GetVpdFieldResponse::Status* status,
                          std::string* vpd_field_value) {
    auto request = std::make_unique<grpc_api::GetVpdFieldRequest>();
    request->set_vpd_field(vpd_field);
    std::unique_ptr<grpc_api::GetVpdFieldResponse> response;
    service()->GetVpdField(std::move(request),
                           GrpcCallbackResponseSaver(&response));

    // Expect the method to return immediately.
    ASSERT_TRUE(response);
    *status = response->status();
    *vpd_field_value = response->vpd_field_value();
  }

  grpc_api::FileDump MakeFileDump(
      const base::FilePath& relative_file_path,
      const base::FilePath& canonical_relative_file_path,
      const std::string& file_contents) const {
    grpc_api::FileDump file_dump;
    file_dump.set_path(temp_dir_.GetPath().Append(relative_file_path).value());
    file_dump.set_canonical_path(
        temp_dir_.GetPath().Append(canonical_relative_file_path).value());
    file_dump.set_contents(file_contents);
    return file_dump;
  }

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

 private:
  base::test::TaskEnvironment task_environment_{
      base::test::TaskEnvironment::ThreadingMode::MAIN_THREAD_ONLY};
  base::ScopedTempDir temp_dir_;
  StrictMock<MockGrpcServiceDelegate> delegate_;
  GrpcService service_{&delegate_};
};

TEST_F(GrpcServiceTest, SendMessageToUi) {
  constexpr char kFakeJsonMessage[] = "Fake Message From Wilco DTC to UI";
  std::unique_ptr<grpc_api::SendMessageToUiResponse> response;
  ExecuteSendMessageToUi(kFakeJsonMessage, &response);
  ASSERT_TRUE(response);
  EXPECT_EQ(response->response_json_message(), kFakeJsonMessage);
}

TEST_F(GrpcServiceTest, GetProcDataUnsetType) {
  std::vector<grpc_api::FileDump> file_dumps;
  ExecuteGetProcData(grpc_api::GetProcDataRequest::TYPE_UNSET, &file_dumps);

  EXPECT_TRUE(file_dumps.empty())
      << "Obtained: "
      << GetProtosRangeDebugString(file_dumps.begin(), file_dumps.end());
}

TEST_F(GrpcServiceTest, GetSysfsDataUnsetType) {
  std::vector<grpc_api::FileDump> file_dumps;
  ExecuteGetSysfsData(grpc_api::GetSysfsDataRequest::TYPE_UNSET, &file_dumps);

  EXPECT_TRUE(file_dumps.empty())
      << "Obtained: "
      << GetProtosRangeDebugString(file_dumps.begin(), file_dumps.end());
}

TEST_F(GrpcServiceTest, RunRoutineUnsetType) {
  auto request = std::make_unique<grpc_api::RunRoutineRequest>();
  request->set_routine(grpc_api::ROUTINE_UNSET);
  auto response = std::make_unique<grpc_api::RunRoutineResponse>();
  ExecuteRunRoutine(std::move(request), &response,
                    false /* is_valid_request */);
  EXPECT_EQ(response->uuid(), 0);
  EXPECT_EQ(response->status(), grpc_api::ROUTINE_STATUS_INVALID_FIELD);
}

TEST_F(GrpcServiceTest, GetRoutineUpdateUnsetType) {
  std::unique_ptr<grpc_api::GetRoutineUpdateResponse> response;
  constexpr bool kIncludeOutput = false;
  ExecuteGetRoutineUpdate(kFakeUuid,
                          grpc_api::GetRoutineUpdateRequest::COMMAND_UNSET,
                          kIncludeOutput, &response);
  ASSERT_TRUE(response);
  EXPECT_EQ(response->uuid(), kFakeUuid);
  EXPECT_EQ(response->status(), grpc_api::ROUTINE_STATUS_INVALID_FIELD);
}

// Test that GetEcTelemetry() response contains expected |status| and |payload|
// field values.
TEST_F(GrpcServiceTest, GetEcTelemetryErrorAccessingDriver) {
  std::unique_ptr<grpc_api::GetEcTelemetryResponse> response;
  ExecuteGetEcTelemetry(FakeFileContents(), &response);
  ASSERT_TRUE(response);
  auto expected_response = MakeGetEcTelemetryResponse(
      grpc_api::GetEcTelemetryResponse::STATUS_ERROR_ACCESSING_DRIVER, "");
  EXPECT_THAT(*response, ProtobufEquals(*expected_response))
      << "Actual response: {" << response->ShortDebugString() << "}";
}

// Test that GetAvailableRoutines returns the expected list of diagnostic
// routines.
TEST_F(GrpcServiceTest, GetAvailableRoutines) {
  std::unique_ptr<grpc_api::GetAvailableRoutinesResponse> response;
  ExecuteGetAvailableRoutines(&response);
  auto expected_response = MakeGetAvailableRoutinesResponse();
  EXPECT_THAT(*response, ProtobufEquals(*expected_response))
      << "Actual response: {" << response->ShortDebugString() << "}";
}

// Test that we can request that the battery routine be run.
TEST_F(GrpcServiceTest, RunBatteryRoutine) {
  std::unique_ptr<grpc_api::RunRoutineResponse> response;
  ExecuteRunRoutine(MakeRunBatteryRoutineRequest(), &response,
                    true /* is_valid_request */);
  auto expected_response = MakeRunRoutineResponse();
  EXPECT_THAT(*response, ProtobufEquals(*expected_response))
      << "Actual response: {" << response->ShortDebugString() << "}";
}

// Test that a battery routine with no parameters will fail.
TEST_F(GrpcServiceTest, RunBatteryRoutineNoParameters) {
  std::unique_ptr<grpc_api::RunRoutineResponse> response;
  auto request = std::make_unique<grpc_api::RunRoutineRequest>();
  request->set_routine(grpc_api::ROUTINE_BATTERY);
  ExecuteRunRoutine(std::move(request), &response,
                    false /* is_valid_request */);
  EXPECT_EQ(response->uuid(), 0);
  EXPECT_EQ(response->status(), grpc_api::ROUTINE_STATUS_INVALID_FIELD);
}

// Test that we can request that the battery_sysfs routine be run.
TEST_F(GrpcServiceTest, RunBatterySysfsRoutine) {
  std::unique_ptr<grpc_api::RunRoutineResponse> response;
  ExecuteRunRoutine(MakeRunBatterySysfsRoutineRequest(), &response,
                    true /* is_valid_request */);
  auto expected_response = MakeRunRoutineResponse();
  EXPECT_THAT(*response, ProtobufEquals(*expected_response))
      << "Actual response: {" << response->ShortDebugString() << "}";
}

// Test that a battery_sysfs routine with no parameters will fail.
TEST_F(GrpcServiceTest, RunBatterySysfsRoutineNoParameters) {
  std::unique_ptr<grpc_api::RunRoutineResponse> response;
  auto request = std::make_unique<grpc_api::RunRoutineRequest>();
  request->set_routine(grpc_api::ROUTINE_BATTERY_SYSFS);
  ExecuteRunRoutine(std::move(request), &response,
                    false /* is_valid_request */);
  EXPECT_EQ(response->uuid(), 0);
  EXPECT_EQ(response->status(), grpc_api::ROUTINE_STATUS_INVALID_FIELD);
}

// Test that we can request that the urandom routine be run.
TEST_F(GrpcServiceTest, RunUrandomRoutine) {
  std::unique_ptr<grpc_api::RunRoutineResponse> response;
  ExecuteRunRoutine(MakeRunUrandomRoutineRequest(), &response,
                    true /* is_valid_request */);
  auto expected_response = MakeRunRoutineResponse();
  EXPECT_THAT(*response, ProtobufEquals(*expected_response))
      << "Actual response: {" << response->ShortDebugString() << "}";
}

// Test that a urandom routine with no parameters will fail.
TEST_F(GrpcServiceTest, RunUrandomRoutineNoParameters) {
  std::unique_ptr<grpc_api::RunRoutineResponse> response;
  auto request = std::make_unique<grpc_api::RunRoutineRequest>();
  request->set_routine(grpc_api::ROUTINE_URANDOM);
  ExecuteRunRoutine(std::move(request), &response,
                    false /* is_valid_request */);
  EXPECT_EQ(response->uuid(), 0);
  EXPECT_EQ(response->status(), grpc_api::ROUTINE_STATUS_INVALID_FIELD);
}

// Test that we can request that the floating_point_accuracy routine be run.
TEST_F(GrpcServiceTest, RunFloatingPointAccuracyRoutine) {
  std::unique_ptr<grpc_api::RunRoutineResponse> response;
  ExecuteRunRoutine(MakeRunFloatingPointAccuracyRoutineRequest(), &response,
                    true /* is_valid_request */);
  auto expected_response = MakeRunRoutineResponse();
  EXPECT_THAT(*response, ProtobufEquals(*expected_response))
      << "Actual response: {" << response->ShortDebugString() << "}";
}
// Test that we can request that the prime search routine be run.
TEST_F(GrpcServiceTest, RunPrimeSearchRoutine) {
  std::unique_ptr<grpc_api::RunRoutineResponse> response;
  ExecuteRunRoutine(MakeRunPrimeSearchRoutineRequest(), &response,
                    true /* is_valid_request */);
  auto expected_response = MakeRunRoutineResponse();
  EXPECT_THAT(*response, ProtobufEquals(*expected_response))
      << "Actual response: {" << response->ShortDebugString() << "}";
}

// Test that we can request that the nvme_wear_level routine be run.
TEST_F(GrpcServiceTest, RunNvmeWearLevelRoutine) {
  std::unique_ptr<grpc_api::RunRoutineResponse> response;
  ExecuteRunRoutine(MakeRunNvmeWearLevelRoutineRequest(), &response,
                    true /* is_valid_request */);
  auto expected_response = MakeRunRoutineResponse();
  EXPECT_THAT(*response, ProtobufEquals(*expected_response))
      << "Actual response: {" << response->ShortDebugString() << "}";
}

// Test that a nvme_wear_level routine with no parameters will fail.
TEST_F(GrpcServiceTest, RunNvmeWearLevelRoutineNoParameters) {
  std::unique_ptr<grpc_api::RunRoutineResponse> response;
  auto request = std::make_unique<grpc_api::RunRoutineRequest>();
  request->set_routine(grpc_api::ROUTINE_NVME_WEAR_LEVEL);
  ExecuteRunRoutine(std::move(request), &response,
                    false /* is_valid_request */);
  EXPECT_EQ(response->uuid(), 0);
  EXPECT_EQ(response->status(), grpc_api::ROUTINE_STATUS_INVALID_FIELD);
}

// Test that we can request that the nvme_self_test routine for short time be
// run.
TEST_F(GrpcServiceTest, RunNvmeSelfTestShortRoutine) {
  std::unique_ptr<grpc_api::RunRoutineResponse> response;
  ExecuteRunRoutine(MakeRunNvmeShortSelfTestRoutineRequest(), &response,
                    true /* is_valid_request */);
  auto expected_response = MakeRunRoutineResponse();
  EXPECT_THAT(*response, ProtobufEquals(*expected_response))
      << "Actual response: {" << response->ShortDebugString() << "}";
}

// Test that linear read routine can be run.
TEST_F(GrpcServiceTest, RunDiskLinearReadRoutine) {
  std::unique_ptr<grpc_api::RunRoutineResponse> response;
  auto request = std::make_unique<grpc_api::RunRoutineRequest>();
  request->set_routine(grpc_api::ROUTINE_DISK_LINEAR_READ);
  request->mutable_disk_linear_read_params()->set_length_seconds(10);
  request->mutable_disk_linear_read_params()->set_file_size_mb(1024);
  ExecuteRunRoutine(std::move(request), &response, true /* is_valid_request */);
  auto expected_response = MakeRunRoutineResponse();
  EXPECT_THAT(*response, ProtobufEquals(*expected_response))
      << "Actual response: {" << response->ShortDebugString() << "}";
}

// Test that a nvme_self_test routine for short time with no parameters will
// fail.
TEST_F(GrpcServiceTest, RunNvmeSelfTestShortRoutineNoParameters) {
  std::unique_ptr<grpc_api::RunRoutineResponse> response;
  auto request = std::make_unique<grpc_api::RunRoutineRequest>();
  request->set_routine(grpc_api::ROUTINE_NVME_SHORT_SELF_TEST);
  ExecuteRunRoutine(std::move(request), &response,
                    false /* is_valid_request */);
  EXPECT_EQ(response->uuid(), 0);
  EXPECT_EQ(response->status(), grpc_api::ROUTINE_STATUS_INVALID_FIELD);
}

// Test that a linear read routine with no parameters will fail.
TEST_F(GrpcServiceTest, RunDiskLinearReadRoutineNoParameters) {
  std::unique_ptr<grpc_api::RunRoutineResponse> response;
  auto request = std::make_unique<grpc_api::RunRoutineRequest>();
  request->set_routine(grpc_api::ROUTINE_DISK_LINEAR_READ);
  ExecuteRunRoutine(std::move(request), &response,
                    false /* is_valid_request */);
  EXPECT_EQ(response->uuid(), 0);
  EXPECT_EQ(response->status(), grpc_api::ROUTINE_STATUS_INVALID_FIELD);
}

// Test that we can request that the nvme_self_test routine for extended time
// be run.
TEST_F(GrpcServiceTest, RunNvmeSelfTestLongRoutine) {
  std::unique_ptr<grpc_api::RunRoutineResponse> response;
  ExecuteRunRoutine(MakeRunNvmeLongSelfTestRoutineRequest(), &response,
                    true /* is_valid_request */);
  auto expected_response = MakeRunRoutineResponse();
  EXPECT_THAT(*response, ProtobufEquals(*expected_response))
      << "Actual response: {" << response->ShortDebugString() << "}";
}

// Test that random read routine can be run.
TEST_F(GrpcServiceTest, RunDiskRandomReadRoutine) {
  std::unique_ptr<grpc_api::RunRoutineResponse> response;
  auto request = std::make_unique<grpc_api::RunRoutineRequest>();
  request->set_routine(grpc_api::ROUTINE_DISK_RANDOM_READ);
  request->mutable_disk_random_read_params()->set_length_seconds(10);
  request->mutable_disk_random_read_params()->set_file_size_mb(1024);
  ExecuteRunRoutine(std::move(request), &response, true /* is_valid_request */);
  auto expected_response = MakeRunRoutineResponse();
  EXPECT_THAT(*response, ProtobufEquals(*expected_response))
      << "Actual response: {" << response->ShortDebugString() << "}";
}

// Test that a nvme_self_test routine for extended time with no parameters will
// fail.
TEST_F(GrpcServiceTest, RunNvmeSelfTestLongRoutineNoParameters) {
  std::unique_ptr<grpc_api::RunRoutineResponse> response;
  auto request = std::make_unique<grpc_api::RunRoutineRequest>();
  request->set_routine(grpc_api::ROUTINE_NVME_LONG_SELF_TEST);
  ExecuteRunRoutine(std::move(request), &response,
                    false /* is_valid_request */);
  EXPECT_EQ(response->uuid(), 0);
  EXPECT_EQ(response->status(), grpc_api::ROUTINE_STATUS_INVALID_FIELD);
}

// Test that a random read routine with no parameters will fail.
TEST_F(GrpcServiceTest, RunDiskRandomReadRoutineNoParameters) {
  std::unique_ptr<grpc_api::RunRoutineResponse> response;
  auto request = std::make_unique<grpc_api::RunRoutineRequest>();
  request->set_routine(grpc_api::ROUTINE_DISK_RANDOM_READ);
  ExecuteRunRoutine(std::move(request), &response,
                    false /* is_valid_request */);
  EXPECT_EQ(response->uuid(), 0);
  EXPECT_EQ(response->status(), grpc_api::ROUTINE_STATUS_INVALID_FIELD);
}

// Test that a prime search routine with no parameters will fail.
TEST_F(GrpcServiceTest, RunPrimeSearchRoutineNoParameters) {
  std::unique_ptr<grpc_api::RunRoutineResponse> response;
  auto request = std::make_unique<grpc_api::RunRoutineRequest>();
  request->set_routine(grpc_api::ROUTINE_PRIME_SEARCH);
  ExecuteRunRoutine(std::move(request), &response,
                    false /* is_valid_request */);
  EXPECT_EQ(response->uuid(), 0);
  EXPECT_EQ(response->status(), grpc_api::ROUTINE_STATUS_INVALID_FIELD);
}

// Test that an empty string is a valid result.
TEST_F(GrpcServiceTest, GetConfigurationDataEmpty) {
  std::unique_ptr<grpc_api::GetConfigurationDataResponse> response;
  ExecuteGetConfigurationData("", &response);
  EXPECT_EQ(response->json_configuration_data(), "");
}

TEST_F(GrpcServiceTest, GetConfigurationData) {
  // The JSON configuration data is passed through from the cloud to DTC binary
  // and might not be in JSON format.
  constexpr char kFakeJsonConfigurationData[] = "Fake JSON Configuration Data";
  std::unique_ptr<grpc_api::GetConfigurationDataResponse> response;
  ExecuteGetConfigurationData(kFakeJsonConfigurationData, &response);
  EXPECT_EQ(response->json_configuration_data(), kFakeJsonConfigurationData);
}

TEST_F(GrpcServiceTest, GetVpdFieldUnset) {
  grpc_api::GetVpdFieldResponse::Status status;
  std::string vpd_field_value;
  ASSERT_NO_FATAL_FAILURE(ExecuteGetVpdField(
      grpc_api::GetVpdFieldRequest::FIELD_UNSET, &status, &vpd_field_value));
  EXPECT_EQ(status,
            grpc_api::GetVpdFieldResponse::STATUS_ERROR_VPD_FIELD_UNKNOWN);
  EXPECT_TRUE(vpd_field_value.empty());
}

TEST_F(GrpcServiceTest, GetDriveSystemDataTypeUnknown) {
  auto request = std::make_unique<grpc_api::GetDriveSystemDataRequest>();
  std::unique_ptr<grpc_api::GetDriveSystemDataResponse> response;
  service()->GetDriveSystemData(std::move(request),
                                GrpcCallbackResponseSaver(&response));

  auto expected_response =
      std::make_unique<grpc_api::GetDriveSystemDataResponse>();
  expected_response->set_status(
      grpc_api::GetDriveSystemDataResponse::STATUS_ERROR_REQUEST_TYPE_UNKNOWN);
  EXPECT_THAT(*response, ProtobufEquals(*expected_response))
      << "Actual response: {" << response->ShortDebugString() << "}";
}

TEST_F(GrpcServiceTest, GetDriveSystemDataInternalError) {
  auto request = std::make_unique<grpc_api::GetDriveSystemDataRequest>();
  request->set_type(grpc_api::GetDriveSystemDataRequest::SMART_ATTRIBUTES);
  EXPECT_CALL(*delegate(), GetDriveSystemData(_, _))
      .WillOnce(WithArgs<1>(
          Invoke([](const base::Callback<void(const std::string& payload,
                                              bool success)>& callback) {
            callback.Run("", false /* success */);
          })));

  std::unique_ptr<grpc_api::GetDriveSystemDataResponse> response;
  service()->GetDriveSystemData(std::move(request),
                                GrpcCallbackResponseSaver(&response));

  auto expected_response =
      std::make_unique<grpc_api::GetDriveSystemDataResponse>();
  expected_response->set_status(
      grpc_api::GetDriveSystemDataResponse::STATUS_ERROR_REQUEST_PROCESSING);
  EXPECT_THAT(*response, ProtobufEquals(*expected_response))
      << "Actual response: {" << response->ShortDebugString() << "}";
}

TEST_F(GrpcServiceTest, RequestBluetoothDataNotification) {
  auto request =
      std::make_unique<grpc_api::RequestBluetoothDataNotificationRequest>();

  EXPECT_CALL(*delegate(), RequestBluetoothDataNotification());

  base::RunLoop run_loop;
  service()->RequestBluetoothDataNotification(
      std::move(request),
      base::Bind(
          [](base::Closure callback, grpc::Status status,
             std::unique_ptr<
                 grpc_api::RequestBluetoothDataNotificationResponse>) {
            callback.Run();
          },
          run_loop.QuitClosure()));

  run_loop.Run();
}

class GetStatefulPartitionAvailableCapacityTest
    : public GrpcServiceTest,
      public testing::WithParamInterface<std::tuple<
          base::Callback<chromeos::cros_healthd::mojom::TelemetryInfoPtr()>,
          grpc_api::GetStatefulPartitionAvailableCapacityResponse::Status,
          int32_t>> {
 protected:
  // Accessors to individual test parameters from the test parameter tuple
  // returned by gtest's GetParam():

  chromeos::cros_healthd::mojom::TelemetryInfoPtr get_probe_response() const {
    return std::get<0>(GetParam()).Run();
  }

  grpc_api::GetStatefulPartitionAvailableCapacityResponse::Status
  get_expected_status() const {
    return std::get<1>(GetParam());
  }

  int32_t get_expected_capacity() const { return std::get<2>(GetParam()); }
};

TEST_P(GetStatefulPartitionAvailableCapacityTest, All) {
  const std::vector<chromeos::cros_healthd::mojom::ProbeCategoryEnum>
      kExpectedCategories{
          chromeos::cros_healthd::mojom::ProbeCategoryEnum::kStatefulPartition};

  chromeos::cros_healthd::mojom::TelemetryInfoPtr probe_response =
      get_probe_response();

  EXPECT_CALL(*delegate(), ProbeTelemetryInfo(kExpectedCategories, _))
      .WillOnce(WithArgs<1>(Invoke(
          [&probe_response](
              MockGrpcServiceDelegate::ProbeTelemetryInfoCallback callback) {
            std::move(callback).Run(std::move(probe_response));
          })));

  auto callback_impl =
      [](grpc_api::GetStatefulPartitionAvailableCapacityResponse::Status status,
         int32_t expected_capacity, base::Closure loop_callback,
         grpc::Status grpcStatus,
         std::unique_ptr<
             grpc_api::GetStatefulPartitionAvailableCapacityResponse> reply) {
        EXPECT_EQ(reply->status(), status);
        EXPECT_EQ(reply->available_capacity_mb(), expected_capacity);
        loop_callback.Run();
      };

  base::RunLoop run_loop;
  auto callback = base::Bind(callback_impl, get_expected_status(),
                             get_expected_capacity(), run_loop.QuitClosure());
  service()->GetStatefulPartitionAvailableCapacity(
      std::make_unique<
          grpc_api::GetStatefulPartitionAvailableCapacityRequest>(),
      callback);
  run_loop.Run();
}

INSTANTIATE_TEST_SUITE_P(
    ,
    GetStatefulPartitionAvailableCapacityTest,
    testing::Values(
        std::make_tuple(
            base::Bind([]() {
              return chromeos::cros_healthd::mojom::TelemetryInfoPtr(nullptr);
            }),
            grpc_api::GetStatefulPartitionAvailableCapacityResponse::
                STATUS_ERROR_REQUEST_PROCESSING,
            0),
        std::make_tuple(
            base::Bind([]() {
              return chromeos::cros_healthd::mojom::TelemetryInfo::New();
            }),
            grpc_api::GetStatefulPartitionAvailableCapacityResponse::
                STATUS_ERROR_REQUEST_PROCESSING,
            0),
        std::make_tuple(
            base::Bind([]() {
              auto probe_response =
                  chromeos::cros_healthd::mojom::TelemetryInfo::New();
              probe_response->stateful_partition_result =
                  chromeos::cros_healthd::mojom::StatefulPartitionResult::
                      NewError(chromeos::cros_healthd::mojom::ProbeError::New(
                          chromeos::cros_healthd::mojom::ErrorType::
                              kSystemUtilityError,
                          ""));
              return probe_response;
            }),
            grpc_api::GetStatefulPartitionAvailableCapacityResponse::
                STATUS_ERROR_REQUEST_PROCESSING,
            0),
        std::make_tuple(
            base::Bind([]() {
              constexpr uint64_t kAvailableBytes = 220403699712ull;
              auto probe_response =
                  chromeos::cros_healthd::mojom::TelemetryInfo::New();
              probe_response
                  ->stateful_partition_result = chromeos::cros_healthd::mojom::
                  StatefulPartitionResult::NewPartitionInfo(
                      chromeos::cros_healthd::mojom::StatefulPartitionInfo::New(
                          kAvailableBytes, 0));
              return probe_response;
            }),
            grpc_api::GetStatefulPartitionAvailableCapacityResponse::STATUS_OK,
            210100)));

class GrpcServiceWithMockSystemInfoServiceTest : public GrpcServiceTest {
 public:
  GrpcServiceWithMockSystemInfoServiceTest() = default;
  ~GrpcServiceWithMockSystemInfoServiceTest() override = default;

  GrpcServiceWithMockSystemInfoServiceTest(
      const GrpcServiceWithMockSystemInfoServiceTest&) = delete;
  GrpcServiceWithMockSystemInfoServiceTest& operator=(
      const GrpcServiceWithMockSystemInfoServiceTest&) = delete;

  void SetUp() override {
    GrpcServiceTest::SetUp();

    auto mock = std::make_unique<StrictMock<MockSystemInfoService>>();
    system_info_service_mock_ = mock.get();
    service()->set_system_info_service_for_testing(std::move(mock));
  }

  void ExecuteGetOsVersion(
      std::unique_ptr<grpc_api::GetOsVersionResponse>* response) {
    auto request = std::make_unique<grpc_api::GetOsVersionRequest>();
    service()->GetOsVersion(std::move(request),
                            GrpcCallbackResponseSaver(response));
  }

 protected:
  // Owned by |service_| from GrpcServiceTest
  MockSystemInfoService* system_info_service_mock_ = nullptr;
};

TEST_F(GrpcServiceWithMockSystemInfoServiceTest, GetOsVersionUnset) {
  EXPECT_CALL(*system_info_service_mock_, GetOsVersion(NotNull()));
  EXPECT_CALL(*system_info_service_mock_, GetOsMilestone(NotNull()));

  std::unique_ptr<grpc_api::GetOsVersionResponse> response;
  ExecuteGetOsVersion(&response);

  ASSERT_TRUE(response);

  EXPECT_TRUE(response->version().empty());
  EXPECT_EQ(response->milestone(), 0);
}

TEST_F(GrpcServiceWithMockSystemInfoServiceTest, GetOsVersion) {
  constexpr char kOsVersion[] = "11932.0.2019_03_20_1100";
  constexpr int kMilestone = 75;

  EXPECT_CALL(*system_info_service_mock_, GetOsVersion(NotNull()))
      .WillOnce(DoAll(WithArgs<0>(SetArgPointee<0>(kOsVersion)), Return(true)));
  EXPECT_CALL(*system_info_service_mock_, GetOsMilestone(NotNull()))
      .WillOnce(DoAll(WithArgs<0>(SetArgPointee<0>(kMilestone)), Return(true)));

  std::unique_ptr<grpc_api::GetOsVersionResponse> response;
  ExecuteGetOsVersion(&response);

  ASSERT_TRUE(response);

  EXPECT_EQ(response->version(), kOsVersion);
  EXPECT_EQ(response->milestone(), kMilestone);
}

class GrpcServiceWithMockSystemFilesServiceTest : public GrpcServiceTest {
 public:
  void SetUp() override {
    GrpcServiceTest::SetUp();

    auto fake = std::make_unique<StrictMock<MockSystemFilesService>>();
    system_files_service_ = fake.get();
    service()->set_system_files_service_for_testing(std::move(fake));
  }

 protected:
  // Owned by |service_| from GrpcServiceTest
  MockSystemFilesService* system_files_service_ = nullptr;
};

TEST_F(GrpcServiceWithMockSystemFilesServiceTest,
       DirectoryAcpiButtonSingleFile) {
  SystemFilesService::FileDumps directory_dump;
  auto single_dump = std::make_unique<SystemFilesService::FileDump>();
  single_dump->contents = FakeFileContents();
  single_dump->path = base::FilePath(kTestFilePath);
  single_dump->canonical_path = base::FilePath(kTestCanonicalFilePath);
  directory_dump.push_back(std::move(single_dump));

  EXPECT_CALL(*system_files_service_,
              GetDirectoryDump(SystemFilesService::Directory::kProcAcpiButton))
      .WillOnce(Return(
          ByMove(MockSystemFilesService::CopyFileDumps(directory_dump))));

  std::vector<grpc_api::FileDump> file_dumps;
  ExecuteGetProcData(grpc_api::GetProcDataRequest::DIRECTORY_ACPI_BUTTON,
                     &file_dumps);

  EXPECT_THAT(file_dumps,
              GrpcDumpsEquivalentWithInternal(ByRef(directory_dump)));
}

TEST_F(GrpcServiceWithMockSystemFilesServiceTest,
       DirectoryAcpiButtonMultiFile) {
  SystemFilesService::FileDumps directory_dump;
  auto first_dump = std::make_unique<SystemFilesService::FileDump>();
  first_dump->contents = FakeFileContents();
  first_dump->path = base::FilePath(kTestFilePath);
  first_dump->canonical_path = base::FilePath(kTestCanonicalFilePath);
  directory_dump.push_back(std::move(first_dump));

  auto second_dump = std::make_unique<SystemFilesService::FileDump>();
  second_dump->contents = FakeFileContents() + "file_2";
  second_dump->path = base::FilePath(kTestFilePath).Append("2");
  second_dump->canonical_path =
      base::FilePath(kTestCanonicalFilePath).Append("3");
  directory_dump.push_back(std::move(second_dump));

  EXPECT_CALL(*system_files_service_,
              GetDirectoryDump(SystemFilesService::Directory::kProcAcpiButton))
      .WillOnce(Return(
          ByMove(MockSystemFilesService::CopyFileDumps(directory_dump))));

  std::vector<grpc_api::FileDump> file_dumps;
  ExecuteGetProcData(grpc_api::GetProcDataRequest::DIRECTORY_ACPI_BUTTON,
                     &file_dumps);

  EXPECT_THAT(file_dumps,
              GrpcDumpsEquivalentWithInternal(ByRef(directory_dump)));
}

TEST_F(GrpcServiceWithMockSystemFilesServiceTest, DirectoryAcpiButtonEmpty) {
  EXPECT_CALL(*system_files_service_,
              GetDirectoryDump(SystemFilesService::Directory::kProcAcpiButton))
      .WillOnce(Return(ByMove(SystemFilesService::FileDumps())));

  std::vector<grpc_api::FileDump> file_dumps;
  ExecuteGetProcData(grpc_api::GetProcDataRequest::DIRECTORY_ACPI_BUTTON,
                     &file_dumps);

  EXPECT_EQ(file_dumps.size(), 0);
}

TEST_F(GrpcServiceWithMockSystemFilesServiceTest, DirectoryAcpiButtonMissing) {
  EXPECT_CALL(*system_files_service_,
              GetDirectoryDump(SystemFilesService::Directory::kProcAcpiButton))
      .WillOnce(Return(ByMove(base::nullopt)));

  std::vector<grpc_api::FileDump> file_dumps;
  ExecuteGetProcData(grpc_api::GetProcDataRequest::DIRECTORY_ACPI_BUTTON,
                     &file_dumps);

  EXPECT_EQ(file_dumps.size(), 0);
}

// Tests for the GetProcData() method of GrpcServiceTest when a
// single file is requested.
//
// This is a parameterized test with the following parameters:
// * |proc_data_request_type| - type of the GetProcData() request to be executed
//   (see GetProcDataRequest::Type);
// * |expected_location| - SystemFilesService::File that should be requested
class SingleProcFileGrpcServiceTest
    : public GrpcServiceWithMockSystemFilesServiceTest,
      public testing::WithParamInterface<
          std::tuple<grpc_api::GetProcDataRequest::Type,
                     SystemFilesService::File>> {
 protected:
  // Accessors to individual test parameters from the test parameter tuple
  // returned by gtest's GetParam():

  grpc_api::GetProcDataRequest::Type proc_data_request_type() const {
    return std::get<0>(GetParam());
  }

  SystemFilesService::File expected_location() const {
    return std::get<1>(GetParam());
  }
};

// Test that GetProcData() returns a single item with the requested file data
// when the file exists.
TEST_P(SingleProcFileGrpcServiceTest, Success) {
  SystemFilesService::FileDump file_dump;
  file_dump.contents = FakeFileContents();
  file_dump.path = base::FilePath(kTestFilePath);
  file_dump.canonical_path = base::FilePath(kTestCanonicalFilePath);

  EXPECT_CALL(*system_files_service_, GetFileDump(expected_location()))
      .WillOnce(
          Return(ByMove(MockSystemFilesService::CopyFileDump(file_dump))));

  std::vector<grpc_api::FileDump> file_dumps;
  ExecuteGetProcData(proc_data_request_type(), &file_dumps);

  ASSERT_EQ(file_dumps.size(), 1);

  EXPECT_EQ(file_dumps[0].contents(), file_dump.contents);
  EXPECT_EQ(file_dumps[0].path(), file_dump.path.value());
  EXPECT_EQ(file_dumps[0].canonical_path(), file_dump.canonical_path.value());
}

// Test that GetProcData() returns empty result when the file doesn't exist.
TEST_P(SingleProcFileGrpcServiceTest, NonExisting) {
  EXPECT_CALL(*system_files_service_, GetFileDump(expected_location()))
      .WillOnce(Return(ByMove(base::nullopt)));

  std::vector<grpc_api::FileDump> file_dumps;
  ExecuteGetProcData(proc_data_request_type(), &file_dumps);

  EXPECT_EQ(file_dumps.size(), 0);
}

INSTANTIATE_TEST_SUITE_P(
    ,
    SingleProcFileGrpcServiceTest,
    testing::Values(
        std::make_tuple(grpc_api::GetProcDataRequest::FILE_UPTIME,
                        SystemFilesService::File::kProcUptime),
        std::make_tuple(grpc_api::GetProcDataRequest::FILE_MEMINFO,
                        SystemFilesService::File::kProcMeminfo),
        std::make_tuple(grpc_api::GetProcDataRequest::FILE_LOADAVG,
                        SystemFilesService::File::kProcLoadavg),
        std::make_tuple(grpc_api::GetProcDataRequest::FILE_STAT,
                        SystemFilesService::File::kProcStat),
        std::make_tuple(grpc_api::GetProcDataRequest::FILE_NET_NETSTAT,
                        SystemFilesService::File::kProcNetNetstat),
        std::make_tuple(grpc_api::GetProcDataRequest::FILE_NET_DEV,
                        SystemFilesService::File::kProcNetDev),
        std::make_tuple(grpc_api::GetProcDataRequest::FILE_DISKSTATS,
                        SystemFilesService::File::kProcDiskstats),
        std::make_tuple(grpc_api::GetProcDataRequest::FILE_CPUINFO,
                        SystemFilesService::File::kProcCpuinfo),
        std::make_tuple(grpc_api::GetProcDataRequest::FILE_VMSTAT,
                        SystemFilesService::File::kProcVmstat)));

// Tests for the GetSysfsData() method of GrpcServiceTest when a
// directory is requested.
//
// This is a parameterized test with the following parameters:
// * |sysfs_data_request_type| - type of the GetSysfsData() request to be
//    executed (see GetSysfsDataRequest::Type);
// * |expected_location| - SystemFilesService::Directory that should be
//    requested
class SysfsDirectoryGrpcServiceTest
    : public GrpcServiceWithMockSystemFilesServiceTest,
      public testing::WithParamInterface<
          std::tuple<grpc_api::GetSysfsDataRequest::Type,
                     SystemFilesService::Directory>> {
 protected:
  // Accessors to individual test parameters constructed from the test parameter
  // tuple returned by gtest's GetParam():
  grpc_api::GetSysfsDataRequest::Type sysfs_data_request_type() const {
    return std::get<0>(GetParam());
  }

  SystemFilesService::Directory expected_location() const {
    return std::get<1>(GetParam());
  }
};

// Test that GetSysfsData() returns a single file when called on a directory
// containing a single file.
TEST_P(SysfsDirectoryGrpcServiceTest, SingleFile) {
  SystemFilesService::FileDumps directory_dump;
  auto single_dump = std::make_unique<SystemFilesService::FileDump>();
  single_dump->contents = FakeFileContents();
  single_dump->path = base::FilePath(kTestFilePath);
  single_dump->canonical_path = base::FilePath(kTestCanonicalFilePath);
  directory_dump.push_back(std::move(single_dump));

  EXPECT_CALL(*system_files_service_, GetDirectoryDump(expected_location()))
      .WillOnce(Return(
          ByMove(MockSystemFilesService::CopyFileDumps(directory_dump))));

  std::vector<grpc_api::FileDump> file_dumps;
  ExecuteGetSysfsData(sysfs_data_request_type(), &file_dumps);

  EXPECT_THAT(file_dumps,
              GrpcDumpsEquivalentWithInternal(ByRef(directory_dump)));
}

// Test that GetSysfsData() returns a multiple files when called on a directory
// containing multiple files.
TEST_P(SysfsDirectoryGrpcServiceTest, MultiFile) {
  SystemFilesService::FileDumps directory_dump;
  auto first_dump = std::make_unique<SystemFilesService::FileDump>();
  first_dump->contents = FakeFileContents();
  first_dump->path = base::FilePath(kTestFilePath);
  first_dump->canonical_path = base::FilePath(kTestCanonicalFilePath);
  directory_dump.push_back(std::move(first_dump));

  auto second_dump = std::make_unique<SystemFilesService::FileDump>();
  second_dump->contents = FakeFileContents() + "file_2";
  second_dump->path = base::FilePath(kTestFilePath).Append("2");
  second_dump->canonical_path =
      base::FilePath(kTestCanonicalFilePath).Append("3");
  directory_dump.push_back(std::move(second_dump));

  EXPECT_CALL(*system_files_service_, GetDirectoryDump(expected_location()))
      .WillOnce(Return(
          ByMove(MockSystemFilesService::CopyFileDumps(directory_dump))));

  std::vector<grpc_api::FileDump> file_dumps;
  ExecuteGetSysfsData(sysfs_data_request_type(), &file_dumps);

  EXPECT_THAT(file_dumps,
              GrpcDumpsEquivalentWithInternal(ByRef(directory_dump)));
}

// Test that GetSysfsData() returns an empty result when the directory doesn't
// exist.
TEST_P(SysfsDirectoryGrpcServiceTest, NonExisting) {
  EXPECT_CALL(*system_files_service_, GetDirectoryDump(expected_location()))
      .WillOnce(Return(ByMove(base::nullopt)));

  std::vector<grpc_api::FileDump> file_dumps;
  ExecuteGetSysfsData(sysfs_data_request_type(), &file_dumps);

  EXPECT_EQ(file_dumps.size(), 0);
}

// Test that GetSysfsData() returns an empty result when the directory is
// empty.
TEST_P(SysfsDirectoryGrpcServiceTest, Empty) {
  EXPECT_CALL(*system_files_service_, GetDirectoryDump(expected_location()))
      .WillOnce(Return(ByMove(SystemFilesService::FileDumps())));

  std::vector<grpc_api::FileDump> file_dumps;
  ExecuteGetSysfsData(sysfs_data_request_type(), &file_dumps);

  EXPECT_EQ(file_dumps.size(), 0);
}

INSTANTIATE_TEST_SUITE_P(
    ,
    SysfsDirectoryGrpcServiceTest,
    testing::Values(
        std::make_tuple(grpc_api::GetSysfsDataRequest::CLASS_HWMON,
                        SystemFilesService::Directory::kSysClassHwmon),
        std::make_tuple(grpc_api::GetSysfsDataRequest::CLASS_THERMAL,
                        SystemFilesService::Directory::kSysClassThermal),
        std::make_tuple(grpc_api::GetSysfsDataRequest::FIRMWARE_DMI_TABLES,
                        SystemFilesService::Directory::kSysFirmwareDmiTables),
        std::make_tuple(grpc_api::GetSysfsDataRequest::CLASS_POWER_SUPPLY,
                        SystemFilesService::Directory::kSysClassPowerSupply),
        std::make_tuple(grpc_api::GetSysfsDataRequest::CLASS_BACKLIGHT,
                        SystemFilesService::Directory::kSysClassBacklight),
        std::make_tuple(grpc_api::GetSysfsDataRequest::CLASS_NETWORK,
                        SystemFilesService::Directory::kSysClassNetwork),
        std::make_tuple(grpc_api::GetSysfsDataRequest::DEVICES_SYSTEM_CPU,
                        SystemFilesService::Directory::kSysDevicesSystemCpu)));

// Tests for the GetEcTelemetry() method of GrpcServiceTest.
//
// This is a parameterized test with the following parameters:
// * |request_payload| - payload of the GetEcTelemetry() request;
// * |expected_response_status| - expected GetEcTelemetry() response status;
// * |expected_response_payload| - expected GetEcTelemetry() response payload.
class GetEcTelemetryGrpcServiceTest
    : public GrpcServiceTest,
      public testing::WithParamInterface<
          std::tuple<std::string /* request_payload */,
                     grpc_api::GetEcTelemetryResponse::
                         Status /* expected_response_status */,
                     std::string /* expected_response_payload */>> {
 protected:
  std::string request_payload() const { return std::get<0>(GetParam()); }

  grpc_api::GetEcTelemetryResponse::Status expected_response_status() const {
    return std::get<1>(GetParam());
  }

  std::string expected_response_payload() const {
    return std::get<2>(GetParam());
  }

  base::FilePath devfs_telemetry_file() const {
    return temp_dir_path().Append(kEcGetTelemetryFilePath);
  }
};

// Test that GetEcTelemetry() response contains expected |status| and |payload|
// field values.
TEST_P(GetEcTelemetryGrpcServiceTest, Base) {
  // Write request and response payload because EC telemetry char device is
  // non-seekable.
  EXPECT_TRUE(WriteFileAndCreateParentDirs(
      devfs_telemetry_file(), request_payload() + expected_response_payload()));
  std::unique_ptr<grpc_api::GetEcTelemetryResponse> response;
  ExecuteGetEcTelemetry(request_payload(), &response);
  ASSERT_TRUE(response);
  auto expected_response = MakeGetEcTelemetryResponse(
      expected_response_status(), expected_response_payload());
  EXPECT_THAT(*response, ProtobufEquals(*expected_response))
      << "Actual response: {" << response->ShortDebugString() << "}";
}

INSTANTIATE_TEST_SUITE_P(
    ,
    GetEcTelemetryGrpcServiceTest,
    testing::Values(
        std::make_tuple(FakeFileContents(),
                        grpc_api::GetEcTelemetryResponse::STATUS_OK,
                        FakeFileContents()),
        std::make_tuple(std::string("A", kEcGetTelemetryPayloadMaxSize),
                        grpc_api::GetEcTelemetryResponse::STATUS_OK,
                        std::string("B", kEcGetTelemetryPayloadMaxSize)),
        std::make_tuple(
            "",
            grpc_api::GetEcTelemetryResponse::STATUS_ERROR_INPUT_PAYLOAD_EMPTY,
            ""),
        std::make_tuple(std::string("A", kEcGetTelemetryPayloadMaxSize + 1),
                        grpc_api::GetEcTelemetryResponse::
                            STATUS_ERROR_INPUT_PAYLOAD_MAX_SIZE_EXCEEDED,
                        "")));

// Tests for the PerformWebRequest() method of GrpcService.
//
// This is a parameterized test with the following parameters:
//
// The input arguments to create a PerformWebRequestParameter:
// * |http_method| - gRPC PerformWebRequest HTTP method.
// * |url| - gRPC PerformWebRequest URL.
// * |headers| - gRPC PerformWebRequest headers list.
// * |request_body| - gRPC PerformWebRequest request body.
//
// The intermediate parameters to verify by the test:
// * |delegate_http_method| - this is an optional value, a nullptr if the
//                            intermediate verification is not needed.
//                            GrpcService's Delegate's HTTP
//                            method to verify the mapping between gRPC and
//                            Delegate's HTTP method names.
//
// The expected response values to verify PerformWebRequestResponse:
// * |status| - gRPC PerformWebRequestResponse status.
// * |http_status| - this is an optional value. gRPC PerformWebRequestResponse
//                   HTTP status. If there is no HTTP status needed for
//                   the passed |status|, pass a nullptr.
// * |response_body| - this is an optional value. gRPC PerformWebRequestResponse
//                     body. If not set, pass a nullptr.
class PerformWebRequestGrpcServiceTest
    : public GrpcServiceTest,
      public testing::WithParamInterface<
          std::tuple<grpc_api::PerformWebRequestParameter::HttpMethod,
                     std::string /* URL */,
                     std::vector<std::string> /* headers */,
                     std::string /* request body */,
                     const DelegateWebRequestHttpMethod*,
                     grpc_api::PerformWebRequestResponse::Status /* status */,
                     const int* /* HTTP status */,
                     const char* /* response body */>> {
 protected:
  grpc_api::PerformWebRequestParameter::HttpMethod http_method() {
    return std::get<0>(GetParam());
  }
  std::string url() const { return std::get<1>(GetParam()); }
  std::vector<std::string> headers() const { return std::get<2>(GetParam()); }
  std::string request_body() const { return std::get<3>(GetParam()); }
  const DelegateWebRequestHttpMethod* delegate_http_method() const {
    return std::get<4>(GetParam());
  }
  grpc_api::PerformWebRequestResponse::Status status() const {
    return std::get<5>(GetParam());
  }
  const int* http_status() const { return std::get<6>(GetParam()); }
  const char* response_body() const { return std::get<7>(GetParam()); }
};

// Tests that PerformWebRequest() returns an appropriate status and HTTP status
// code.
TEST_P(PerformWebRequestGrpcServiceTest, PerformWebRequest) {
  std::unique_ptr<grpc_api::PerformWebRequestResponse> response;
  ExecutePerformWebRequest(http_method(), url(), headers(), request_body(),
                           delegate_http_method(), &response);
  ASSERT_TRUE(response);

  auto expected_response =
      MakePerformWebRequestResponse(status(), http_status(), response_body());
  EXPECT_THAT(*response, ProtobufEquals(*expected_response))
      << "Actual response: {" << response->ShortDebugString() << "}";
}

// Test cases to run a PerformWebRequest test.
// Make sure that the delegate_http_header is not set if the flow does not
// involve the calls to GrpcService::Delegate.
INSTANTIATE_TEST_SUITE_P(
    ,
    PerformWebRequestGrpcServiceTest,
    testing::Values(
        // Tests an incorrect HTTP method.
        std::make_tuple(grpc_api::PerformWebRequestParameter::HTTP_METHOD_UNSET,
                        kCorrectUrl,
                        std::vector<std::string>() /* headers */,
                        "" /* request_body */,
                        nullptr /* delegate_http_method */,
                        grpc_api::PerformWebRequestResponse ::
                            STATUS_ERROR_REQUIRED_FIELD_MISSING,
                        nullptr /* http_status */,
                        nullptr /* response_body */),
        // Tests an empty URL.
        std::make_tuple(
            grpc_api::PerformWebRequestParameter::HTTP_METHOD_GET,
            "" /* url */,
            std::vector<std::string>() /* headers */,
            "" /* request_body */,
            nullptr /* delegate_http_method */,
            grpc_api::PerformWebRequestResponse ::STATUS_ERROR_INVALID_URL,
            nullptr /* http_status */,
            nullptr /* response_body */),
        // Tests a non-HTTPS URL.
        std::make_tuple(
            grpc_api::PerformWebRequestParameter::HTTP_METHOD_PUT,
            kBadNonHttpsUrl,
            std::vector<std::string>() /* headers */,
            "" /* request_body */,
            nullptr /* delegate_http_method */,
            grpc_api::PerformWebRequestResponse::STATUS_ERROR_INVALID_URL,
            nullptr /* http_status */,
            nullptr /* response_body */),
        // Tests the maximum allowed number of headers with HTTP method GET.
        std::make_tuple(grpc_api::PerformWebRequestParameter::HTTP_METHOD_GET,
                        kCorrectUrl,
                        std::vector<std::string>(
                            kMaxNumberOfHeadersInPerformWebRequestParameter,
                            ""),
                        "" /* request_body */,
                        &kDelegateWebRequestHttpMethodGet,
                        grpc_api::PerformWebRequestResponse::STATUS_OK,
                        &kHttpStatusOk,
                        kFakeWebResponseBody),
        // The HTTP method is HEAD.
        std::make_tuple(grpc_api::PerformWebRequestParameter::HTTP_METHOD_HEAD,
                        kCorrectUrl,
                        std::vector<std::string>(
                            kMaxNumberOfHeadersInPerformWebRequestParameter,
                            ""),
                        "" /* request_body */,
                        &kDelegateWebRequestHttpMethodHead,
                        grpc_api::PerformWebRequestResponse::STATUS_OK,
                        &kHttpStatusOk,
                        kFakeWebResponseBody),
        // The HTTP method is POST.
        std::make_tuple(grpc_api::PerformWebRequestParameter::HTTP_METHOD_POST,
                        kCorrectUrl,
                        std::vector<std::string>() /* headers */,
                        "" /* request_body */,
                        &kDelegateWebRequestHttpMethodPost,
                        grpc_api::PerformWebRequestResponse::STATUS_OK,
                        &kHttpStatusOk,
                        kFakeWebResponseBody),
        // The HTTP method is PATCH.
        std::make_tuple(grpc_api::PerformWebRequestParameter::HTTP_METHOD_PATCH,
                        kCorrectUrl,
                        std::vector<std::string>() /* headers */,
                        "" /* request_body */,
                        &kDelegateWebRequestHttpMethodPatch,
                        grpc_api::PerformWebRequestResponse::STATUS_OK,
                        &kHttpStatusOk,
                        kFakeWebResponseBody),
        // Tests the minimum not allowed number of headers.
        std::make_tuple(
            grpc_api::PerformWebRequestParameter::HTTP_METHOD_GET,
            kCorrectUrl,
            std::vector<std::string>(
                kMaxNumberOfHeadersInPerformWebRequestParameter + 1, ""),
            "" /* request_body */,
            nullptr /* delegate_http_method */,
            grpc_api::PerformWebRequestResponse::STATUS_ERROR_MAX_SIZE_EXCEEDED,
            nullptr /* http_status */,
            nullptr /* response_body */),
        // Tests the total size of "string" and "byte" fields of
        // PerformWebRequestParameter = 1Mb, the HTTP method is PUT.
        std::make_tuple(grpc_api::PerformWebRequestParameter::HTTP_METHOD_PUT,
                        kCorrectUrl,
                        std::vector<std::string>() /* headers */,
                        std::string(kMaxPerformWebRequestParameterSizeInBytes -
                                        strlen(kCorrectUrl),
                                    'A'),
                        &kDelegateWebRequestHttpMethodPut,
                        grpc_api::PerformWebRequestResponse::STATUS_OK,
                        &kHttpStatusOk,
                        kFakeWebResponseBody),
        // Tests the total size of "string" and "byte" fields of
        // PerformWebRequestParameter > 1Mb.
        std::make_tuple(
            grpc_api::PerformWebRequestParameter::HTTP_METHOD_GET,
            kCorrectUrl,
            std::vector<std::string>() /* headers */,
            std::string(kMaxPerformWebRequestParameterSizeInBytes, 'A'),
            nullptr /* delegate_http_method */,
            grpc_api::PerformWebRequestResponse::STATUS_ERROR_MAX_SIZE_EXCEEDED,
            nullptr /* http_status */,
            nullptr /* response_body */)));

// Tests for the GetRoutineUpdate() method of GrpcService.
//
// This is a parameterized test with the following parameters:
//
// The input arguments to create a GetRoutineUpdateRequest:
// * |command| - gRPC GetRoutineUpdateRequest command.
class GetRoutineUpdateRequestGrpcServiceTest
    : public GrpcServiceTest,
      public testing::WithParamInterface<
          grpc_api::GetRoutineUpdateRequest::Command /* command */> {
 protected:
  grpc_api::GetRoutineUpdateRequest::Command command() const {
    return GetParam();
  }
};

// Tests that GetRoutineUpdate() returns an appropriate uuid, status, progress
// percent, user message and output.
TEST_P(GetRoutineUpdateRequestGrpcServiceTest,
       GetRoutineUpdateRequestWithOutput) {
  std::unique_ptr<grpc_api::GetRoutineUpdateResponse> response;
  constexpr bool kIncludeOutput = true;
  ExecuteGetRoutineUpdate(kFakeUuid, command(), kIncludeOutput, &response);
  ASSERT_TRUE(response);

  auto expected_response =
      MakeGetRoutineUpdateResponse(kFakeUuid, kIncludeOutput);
  EXPECT_THAT(*response, ProtobufEquals(*expected_response))
      << "Actual response: {" << response->ShortDebugString() << "}";
}

// Tests that GetRoutineUpdate() does not return output when include_output is
// false.
TEST_P(GetRoutineUpdateRequestGrpcServiceTest,
       GetRoutineUpdateRequestNoOutput) {
  std::unique_ptr<grpc_api::GetRoutineUpdateResponse> response;
  constexpr bool kIncludeOutput = false;
  ExecuteGetRoutineUpdate(kFakeUuid, command(), kIncludeOutput, &response);
  ASSERT_TRUE(response);

  auto expected_response =
      MakeGetRoutineUpdateResponse(kFakeUuid, kIncludeOutput);
  EXPECT_THAT(*response, ProtobufEquals(*expected_response))
      << "Actual response: {" << response->ShortDebugString() << "}";
}

// Test cases to run a GetRoutineUpdateRequest test.
INSTANTIATE_TEST_SUITE_P(,
                         GetRoutineUpdateRequestGrpcServiceTest,
                         testing::Values(
                             // Test each possible command value.
                             grpc_api::GetRoutineUpdateRequest::RESUME,
                             grpc_api::GetRoutineUpdateRequest::CANCEL,
                             grpc_api::GetRoutineUpdateRequest::GET_STATUS));

// Test for the GetVpdField() method of GrpcService.
//
// This is a parametrized test with the following parameters:
// * |vpd_field| - the requested VPD field.
// * |expected_vpd_field| - SystemFilesService::VpdField that should be
//    requested.
class GetVpdFieldGrpcServiceTest
    : public GrpcServiceWithMockSystemFilesServiceTest,
      public testing::WithParamInterface<
          std::tuple<grpc_api::GetVpdFieldRequest::VpdField /* vpd_field */,
                     SystemFilesService::VpdField /* expected_vpd_field */>> {
 protected:
  grpc_api::GetVpdFieldRequest::VpdField vpd_field() const {
    return std::get<0>(GetParam());
  }
  SystemFilesService::VpdField expected_vpd_field() const {
    return std::get<1>(GetParam());
  }
};

// Test that GetVpdField() returns requested VPD field.
TEST_P(GetVpdFieldGrpcServiceTest, Success) {
  constexpr char kFakeVpdField[] = "VPD test value";

  EXPECT_CALL(*system_files_service_, GetVpdField(expected_vpd_field()))
      .WillOnce(Return(kFakeVpdField));

  grpc_api::GetVpdFieldResponse::Status status;
  std::string vpd_field_value;
  ASSERT_NO_FATAL_FAILURE(
      ExecuteGetVpdField(vpd_field(), &status, &vpd_field_value));

  EXPECT_EQ(status, grpc_api::GetVpdFieldResponse::STATUS_OK);
  EXPECT_EQ(vpd_field_value, kFakeVpdField);
}

// Test that GetVpdField() returns error if VPD field does not exist.
TEST_P(GetVpdFieldGrpcServiceTest, NoVpdField) {
  EXPECT_CALL(*system_files_service_, GetVpdField(expected_vpd_field()))
      .WillOnce(Return(base::nullopt));

  grpc_api::GetVpdFieldResponse::Status status;
  std::string vpd_field_value;
  ASSERT_NO_FATAL_FAILURE(
      ExecuteGetVpdField(vpd_field(), &status, &vpd_field_value));

  EXPECT_EQ(status, grpc_api::GetVpdFieldResponse::STATUS_ERROR_INTERNAL);
  EXPECT_TRUE(vpd_field_value.empty());
}

INSTANTIATE_TEST_SUITE_P(
    ,
    GetVpdFieldGrpcServiceTest,
    testing::Values(
        std::make_tuple(grpc_api::GetVpdFieldRequest::FIELD_SERIAL_NUMBER,
                        SystemFilesService::VpdField::kSerialNumber),
        std::make_tuple(grpc_api::GetVpdFieldRequest::FIELD_MODEL_NAME,
                        SystemFilesService::VpdField::kModelName),
        std::make_tuple(grpc_api::GetVpdFieldRequest::FIELD_ASSET_ID,
                        SystemFilesService::VpdField::kAssetId),
        std::make_tuple(grpc_api::GetVpdFieldRequest::FIELD_SKU_NUMBER,
                        SystemFilesService::VpdField::kSkuNumber),
        std::make_tuple(grpc_api::GetVpdFieldRequest::FIELD_UUID_ID,
                        SystemFilesService::VpdField::kUuid),
        std::make_tuple(grpc_api::GetVpdFieldRequest::FIELD_MANUFACTURE_DATE,
                        SystemFilesService::VpdField::kMfgDate),
        std::make_tuple(grpc_api::GetVpdFieldRequest::FIELD_ACTIVATE_DATE,
                        SystemFilesService::VpdField::kActivateDate),
        std::make_tuple(grpc_api::GetVpdFieldRequest::FIELD_SYSTEM_ID,
                        SystemFilesService::VpdField::kSystemId)));

// Test for the GetDriveSystemData() method of GrpcService.
//
// This is a parametrized test with the following parameters:
// * |vpd_field| - the requested drive system data type
// * |expected_data_type| - the expected internal drive system data type value.
class GetDriveSystemDataGrpcServiceTest
    : public GrpcServiceTest,
      public testing::WithParamInterface<
          std::tuple<grpc_api::GetDriveSystemDataRequest::Type /* data_type */,
                     DelegateDriveSystemDataType /* expected_data_type */>> {
 protected:
  grpc_api::GetDriveSystemDataRequest::Type data_type() const {
    return std::get<0>(GetParam());
  }
  DelegateDriveSystemDataType expected_data_type() const {
    return std::get<1>(GetParam());
  }
};

// Test that GetDriveSystemData() parses gRPC message and calls delegate
// function with appropriate data type.
TEST_P(GetDriveSystemDataGrpcServiceTest, GetDriveSystem) {
  constexpr char kFakeDriveSystemData[] = "Fake DriveSystem data";

  auto request = std::make_unique<grpc_api::GetDriveSystemDataRequest>();
  request->set_type(data_type());
  EXPECT_CALL(*delegate(), GetDriveSystemData(expected_data_type(), _))
      .WillOnce(WithArgs<1>(
          Invoke([kFakeDriveSystemData](
                     const base::Callback<void(const std::string& payload,
                                               bool success)>& callback) {
            callback.Run(kFakeDriveSystemData, true /* success */);
          })));

  std::unique_ptr<grpc_api::GetDriveSystemDataResponse> response;
  service()->GetDriveSystemData(std::move(request),
                                GrpcCallbackResponseSaver(&response));

  auto expected_response =
      std::make_unique<grpc_api::GetDriveSystemDataResponse>();
  expected_response->set_status(
      grpc_api::GetDriveSystemDataResponse::STATUS_OK);
  expected_response->set_payload(kFakeDriveSystemData);
  EXPECT_THAT(*response, ProtobufEquals(*expected_response))
      << "Actual response: {" << response->ShortDebugString() << "}";
}

INSTANTIATE_TEST_SUITE_P(
    ,
    GetDriveSystemDataGrpcServiceTest,
    testing::Values(
        std::make_tuple(grpc_api::GetDriveSystemDataRequest::SMART_ATTRIBUTES,
                        DelegateDriveSystemDataType::kSmartAttributes),
        std::make_tuple(
            grpc_api::GetDriveSystemDataRequest::IDENTITY_ATTRIBUTES,
            DelegateDriveSystemDataType::kIdentityAttributes)));

}  // namespace

}  // namespace diagnostics
