// 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;
              constexpr auto kFakeFilesystem = "ext4";
              constexpr auto kFakeMountSource = "/dev/mmcblk0p1";
              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, kFakeFilesystem,
                          kFakeMountSource));
              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
