// Copyright 2019 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 <limits>
#include <string>
#include <tuple>
#include <type_traits>
#include <vector>

#include <base/bind.h>
#include <base/callback.h>
#include <base/message_loop/message_loop.h>
#include <base/run_loop.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "diagnostics/wilco_dtc_supportd/fake_diagnostics_service.h"
#include "diagnostics/wilco_dtc_supportd/routine_service.h"
#include "mojo/cros_healthd_diagnostics.mojom.h"

using testing::ElementsAreArray;

namespace diagnostics {
namespace mojo_ipc = ::chromeos::cros_healthd::mojom;

namespace {

grpc_api::RunRoutineRequest MakeBatteryRoutineRequest() {
  grpc_api::RunRoutineRequest request;
  request.set_routine(grpc_api::ROUTINE_BATTERY);
  request.mutable_battery_params()->set_low_mah(10);
  request.mutable_battery_params()->set_high_mah(100);
  return request;
}

grpc_api::RunRoutineRequest MakeDefaultBatteryRoutineRequest() {
  grpc_api::RunRoutineRequest request;
  request.set_routine(grpc_api::ROUTINE_BATTERY);
  request.mutable_battery_params();
  return request;
}

grpc_api::RunRoutineRequest MakeBatterySysfsRoutineRequest() {
  grpc_api::RunRoutineRequest request;
  request.set_routine(grpc_api::ROUTINE_BATTERY_SYSFS);
  request.mutable_battery_sysfs_params()->set_maximum_cycle_count(2);
  request.mutable_battery_sysfs_params()->set_percent_battery_wear_allowed(30);
  return request;
}

grpc_api::RunRoutineRequest MakeUrandomRoutineRequest() {
  grpc_api::RunRoutineRequest request;
  request.set_routine(grpc_api::ROUTINE_URANDOM);
  request.mutable_urandom_params()->set_length_seconds(10);
  return request;
}

grpc_api::RunRoutineRequest MakeSmartctlCheckRoutineRequest() {
  grpc_api::RunRoutineRequest request;
  request.set_routine(grpc_api::ROUTINE_SMARTCTL_CHECK);
  request.mutable_smartctl_check_params();
  return request;
}

grpc_api::RunRoutineRequest MakeCpuCacheRoutineRequest() {
  grpc_api::RunRoutineRequest request;
  request.set_routine(grpc_api::ROUTINE_CPU_CACHE);
  request.mutable_cpu_params()->set_length_seconds(10);
  return request;
}

grpc_api::RunRoutineRequest MakeCpuStressRoutineRequest() {
  grpc_api::RunRoutineRequest request;
  request.set_routine(grpc_api::ROUTINE_CPU_STRESS);
  request.mutable_cpu_params()->set_length_seconds(300);
  return request;
}

grpc_api::RunRoutineRequest MakeFloatingPointAccuracyRoutineRequest() {
  grpc_api::RunRoutineRequest request;
  request.set_routine(grpc_api::ROUTINE_FLOATING_POINT_ACCURACY);
  request.mutable_floating_point_accuracy_params()->set_length_seconds(2);
  return request;
}

grpc_api::RunRoutineRequest MakeNvmeWearLevelRoutineRequest() {
  grpc_api::RunRoutineRequest request;
  request.set_routine(grpc_api::ROUTINE_NVME_WEAR_LEVEL);
  request.mutable_nvme_wear_level_params()->set_wear_level_threshold(50);
  return request;
}
grpc_api::RunRoutineRequest MakeNvmeSelfTestShortRoutineRequest() {
  grpc_api::RunRoutineRequest request;
  request.set_routine(grpc_api::ROUTINE_NVME_SHORT_SELF_TEST);
  request.mutable_nvme_short_self_test_params();
  return request;
}

grpc_api::RunRoutineRequest MakeNvmeSelfTestLongRoutineRequest() {
  grpc_api::RunRoutineRequest request;
  request.set_routine(grpc_api::ROUTINE_NVME_LONG_SELF_TEST);
  request.mutable_nvme_long_self_test_params();
  return request;
}

grpc_api::RunRoutineRequest MakeDiskLinearReadRoutineRequest() {
  grpc_api::RunRoutineRequest request;
  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);
  return request;
}

grpc_api::RunRoutineRequest MakeDiskRandomReadRoutineRequest() {
  grpc_api::RunRoutineRequest request;
  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);
  return request;
}

void SaveGetAvailableRoutinesResponse(
    base::Closure callback,
    grpc_api::GetAvailableRoutinesResponse* response,
    const std::vector<grpc_api::DiagnosticRoutine>& returned_routines,
    grpc_api::RoutineServiceStatus service_status) {
  for (const auto& routine : returned_routines)
    response->add_routines(routine);
  response->set_service_status(service_status);
  callback.Run();
}

void SaveRunRoutineResponse(base::Closure callback,
                            grpc_api::RunRoutineResponse* response,
                            int uuid,
                            grpc_api::DiagnosticRoutineStatus status,
                            grpc_api::RoutineServiceStatus service_status) {
  response->set_uuid(uuid);
  response->set_status(status);
  response->set_service_status(service_status);
  callback.Run();
}

void SaveGetRoutineUpdateResponse(
    base::Closure callback,
    grpc_api::GetRoutineUpdateResponse* response,
    int uuid,
    grpc_api::DiagnosticRoutineStatus status,
    int progress_percent,
    grpc_api::DiagnosticRoutineUserMessage user_message,
    const std::string& output,
    const std::string& status_message,
    grpc_api::RoutineServiceStatus service_status) {
  response->set_uuid(uuid);
  response->set_status(status);
  response->set_progress_percent(progress_percent);
  response->set_user_message(user_message);
  response->set_output(output);
  response->set_status_message(status_message);
  response->set_service_status(service_status);
  callback.Run();
}

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

  FakeDiagnosticsService* diagnostics_service() {
    return &diagnostics_service_;
  }

  grpc_api::GetAvailableRoutinesResponse ExecuteGetAvailableRoutines() {
    base::RunLoop run_loop;
    grpc_api::GetAvailableRoutinesResponse response;
    service_.GetAvailableRoutines(base::Bind(
        &SaveGetAvailableRoutinesResponse, run_loop.QuitClosure(), &response));
    run_loop.Run();
    return response;
  }

  grpc_api::RunRoutineResponse ExecuteRunRoutine(
      const grpc_api::RunRoutineRequest& request) {
    base::RunLoop run_loop;
    grpc_api::RunRoutineResponse response;
    service_.RunRoutine(request, base::Bind(&SaveRunRoutineResponse,
                                            run_loop.QuitClosure(), &response));
    run_loop.Run();
    return response;
  }

  grpc_api::GetRoutineUpdateResponse ExecuteGetRoutineUpdate(
      const int uuid,
      const grpc_api::GetRoutineUpdateRequest::Command command,
      const bool include_output) {
    base::RunLoop run_loop;
    grpc_api::GetRoutineUpdateResponse response;
    service_.GetRoutineUpdate(uuid, command, include_output,
                              base::Bind(&SaveGetRoutineUpdateResponse,
                                         run_loop.QuitClosure(), &response));
    run_loop.Run();
    return response;
  }

 private:
  base::MessageLoop message_loop_;
  FakeDiagnosticsService diagnostics_service_;
  RoutineService service_{&diagnostics_service_};
};

// Test that GetAvailableRoutines returns the expected list of routines.
TEST_F(RoutineServiceTest, GetAvailableRoutines) {
  diagnostics_service()->SetGetAvailableRoutinesResponse(
      {mojo_ipc::DiagnosticRoutineEnum::kBatteryCapacity,
       mojo_ipc::DiagnosticRoutineEnum::kBatteryHealth,
       mojo_ipc::DiagnosticRoutineEnum::kSmartctlCheck,
       mojo_ipc::DiagnosticRoutineEnum::kUrandom,
       mojo_ipc::DiagnosticRoutineEnum::kCpuCache,
       mojo_ipc::DiagnosticRoutineEnum::kCpuStress,
       mojo_ipc::DiagnosticRoutineEnum::kFloatingPointAccuracy,
       mojo_ipc::DiagnosticRoutineEnum::kNvmeWearLevel,
       mojo_ipc::DiagnosticRoutineEnum::kNvmeSelfTest,
       mojo_ipc::DiagnosticRoutineEnum::kDiskRead});

  const auto reply = ExecuteGetAvailableRoutines();
  EXPECT_THAT(reply.routines(),
              ElementsAreArray(
                  {grpc_api::ROUTINE_BATTERY, grpc_api::ROUTINE_BATTERY_SYSFS,
                   grpc_api::ROUTINE_SMARTCTL_CHECK, grpc_api::ROUTINE_URANDOM,
                   grpc_api::ROUTINE_CPU_CACHE, grpc_api::ROUTINE_CPU_STRESS,
                   grpc_api::ROUTINE_FLOATING_POINT_ACCURACY,
                   grpc_api::ROUTINE_NVME_WEAR_LEVEL,
                   grpc_api::ROUTINE_NVME_SHORT_SELF_TEST,
                   grpc_api::ROUTINE_NVME_LONG_SELF_TEST,
                   grpc_api::ROUTINE_DISK_LINEAR_READ,
                   grpc_api::ROUTINE_DISK_RANDOM_READ}));
  EXPECT_EQ(reply.service_status(), grpc_api::ROUTINE_SERVICE_STATUS_OK);
}

// Test that an unknown mojo routine enum is handled sanely.
TEST_F(RoutineServiceTest, GetAvailableRoutinesInvalidMojoRoutineEnum) {
  diagnostics_service()->SetGetAvailableRoutinesResponse(
      std::vector<mojo_ipc::DiagnosticRoutineEnum>{
          static_cast<mojo_ipc::DiagnosticRoutineEnum>(
              std::numeric_limits<std::underlying_type<
                  mojo_ipc::DiagnosticRoutineEnum>::type>::max()),
          mojo_ipc::DiagnosticRoutineEnum::kBatteryCapacity});

  const auto reply = ExecuteGetAvailableRoutines();
  EXPECT_THAT(reply.routines(), ElementsAreArray({grpc_api::ROUTINE_BATTERY}));
  EXPECT_EQ(reply.service_status(), grpc_api::ROUTINE_SERVICE_STATUS_OK);
}

// Test that an invalid RunRoutineRequest is handled sanely.
TEST_F(RoutineServiceTest, InvalidRunRoutineRequest) {
  grpc_api::RunRoutineRequest request;
  request.set_routine(static_cast<grpc_api::DiagnosticRoutine>(
      std::numeric_limits<
          std::underlying_type<grpc_api::DiagnosticRoutine>::type>::max()));

  const auto reply = ExecuteRunRoutine(request);
  EXPECT_EQ(reply.uuid(), 0);
  EXPECT_EQ(reply.status(), grpc_api::ROUTINE_STATUS_INVALID_FIELD);
  EXPECT_EQ(reply.service_status(), grpc_api::ROUTINE_SERVICE_STATUS_OK);
}

// Test that a routine reporting an invalid user message is handled sanely.
TEST_F(RoutineServiceTest, GetRoutineUpdateInvalidUserMessage) {
  diagnostics_service()->SetInteractiveUpdate(
      static_cast<mojo_ipc::DiagnosticRoutineUserMessageEnum>(
          std::numeric_limits<std::underlying_type<
              mojo_ipc::DiagnosticRoutineUserMessageEnum>::type>::max()),
      0 /* progress_percent */, "" /* output */);

  const auto update_response = ExecuteGetRoutineUpdate(
      0 /* uuid */, grpc_api::GetRoutineUpdateRequest::GET_STATUS,
      false /* include_output */);
  EXPECT_EQ(update_response.status(), grpc_api::ROUTINE_STATUS_ERROR);
  EXPECT_EQ(update_response.service_status(),
            grpc_api::ROUTINE_SERVICE_STATUS_OK);
}

// Test that a routine update reporting an invalid status is handled sanely.
TEST_F(RoutineServiceTest, InvalidGetRoutineUpdateStatus) {
  diagnostics_service()->SetNonInteractiveUpdate(
      static_cast<mojo_ipc::DiagnosticRoutineStatusEnum>(
          std::numeric_limits<std::underlying_type<
              mojo_ipc::DiagnosticRoutineStatusEnum>::type>::max()),
      "" /* status_message */, 0 /* progress_percent */, "" /* output */);

  const auto update_response = ExecuteGetRoutineUpdate(
      0 /* uuid */, grpc_api::GetRoutineUpdateRequest::GET_STATUS,
      false /* include_output */);
  EXPECT_EQ(update_response.status(), grpc_api::ROUTINE_STATUS_ERROR);
  EXPECT_EQ(update_response.service_status(),
            grpc_api::ROUTINE_SERVICE_STATUS_OK);
}

// Test that a run routine response reporting an invalid status is handled
// sanely.
TEST_F(RoutineServiceTest, InvalidRunRoutineResponseStatus) {
  diagnostics_service()->SetRunSomeRoutineResponse(
      0 /* uuid */,
      static_cast<mojo_ipc::DiagnosticRoutineStatusEnum>(
          std::numeric_limits<std::underlying_type<
              mojo_ipc::DiagnosticRoutineStatusEnum>::type>::max()));

  const auto response = ExecuteRunRoutine(MakeSmartctlCheckRoutineRequest());
  EXPECT_EQ(response.status(), grpc_api::ROUTINE_STATUS_ERROR);
  EXPECT_EQ(response.uuid(), 0);
  EXPECT_EQ(response.service_status(), grpc_api::ROUTINE_SERVICE_STATUS_OK);
}

// Test that an invalid command passed to the routine service is handled sanely.
TEST_F(RoutineServiceTest, GetRoutineUpdateInvalidCommand) {
  diagnostics_service()->SetNonInteractiveUpdate(
      mojo_ipc::DiagnosticRoutineStatusEnum::kReady, "" /* status_message */,
      0 /* progress_percent */, "" /* output */);

  const auto update_response = ExecuteGetRoutineUpdate(
      0 /* uuid */,
      static_cast<grpc_api::GetRoutineUpdateRequest::Command>(
          std::numeric_limits<std::underlying_type<
              grpc_api::GetRoutineUpdateRequest::Command>::type>::max()),
      false /* include_output */);
  EXPECT_EQ(update_response.status(), grpc_api::ROUTINE_STATUS_INVALID_FIELD);
  EXPECT_EQ(update_response.progress_percent(), 0);
  EXPECT_EQ(update_response.user_message(),
            grpc_api::ROUTINE_USER_MESSAGE_UNSET);
  EXPECT_EQ(update_response.output(), "");
  EXPECT_EQ(update_response.status_message(), "");
  EXPECT_EQ(update_response.service_status(),
            grpc_api::ROUTINE_SERVICE_STATUS_OK);
}

// Test that the routine service doesn't attempt to rebind a valid mojo service
// pointer.
TEST_F(RoutineServiceTest, NoRebindService) {
  constexpr uint32_t kExpectedId = 55;
  diagnostics_service()->SetRunSomeRoutineResponse(
      kExpectedId, mojo_ipc::DiagnosticRoutineStatusEnum::kRunning);
  // Send the first mojo IPC to the diagnostics service. This IPC should
  // bootstrap the mojo connection. Ignore the response, because we're only
  // interested in whether or not the next request tries to bootstrap the mojo
  // connection again.
  ExecuteRunRoutine(MakeSmartctlCheckRoutineRequest());

  // Tell the service to respond with an error if a second bootstrapping is
  // requested.
  diagnostics_service()->SetMojoServiceIsAvailable(false);

  // Send another request. This shouldn't see an error, because it shouldn't try
  // to bootstrap the mojo connection a second time.
  const auto reply = ExecuteRunRoutine(MakeSmartctlCheckRoutineRequest());

  // If the bootstrap was requested a second time, we would receive a uuid of 0
  // and a status of grpc_api::FAILED_TO_START.
  EXPECT_EQ(reply.uuid(), kExpectedId);
  EXPECT_EQ(reply.status(), grpc_api::ROUTINE_STATUS_RUNNING);
  EXPECT_EQ(reply.service_status(), grpc_api::ROUTINE_SERVICE_STATUS_OK);
}

// Test that the routine service handles a GetAvailableRoutines request sent
// before wilco_dtc_supportd's mojo service is established.
TEST_F(RoutineServiceTest, GetAvailableRoutinesNoService) {
  diagnostics_service()->SetMojoServiceIsAvailable(false);

  const auto reply = ExecuteGetAvailableRoutines();
  EXPECT_EQ(reply.routines_size(), 0);
  EXPECT_EQ(reply.service_status(),
            grpc_api::ROUTINE_SERVICE_STATUS_UNAVAILABLE);
}

// Test that the routine service handles a RunRoutine request sent before
// wilco_dtc_supportd's mojo service is established.
TEST_F(RoutineServiceTest, RunRoutineNoService) {
  diagnostics_service()->SetMojoServiceIsAvailable(false);

  const auto response = ExecuteRunRoutine(MakeSmartctlCheckRoutineRequest());
  EXPECT_EQ(response.status(), grpc_api::ROUTINE_STATUS_FAILED_TO_START);
  EXPECT_EQ(response.uuid(), 0);
  EXPECT_EQ(response.service_status(),
            grpc_api::ROUTINE_SERVICE_STATUS_UNAVAILABLE);
}

// Test that the routine service handles a GetRoutineUpdate request sent before
// wilco_dtc_supportd's mojo service is established.
TEST_F(RoutineServiceTest, GetRoutineUpdateNoService) {
  diagnostics_service()->SetMojoServiceIsAvailable(false);

  const auto update_response = ExecuteGetRoutineUpdate(
      0 /* uuid */, grpc_api::GetRoutineUpdateRequest::GET_STATUS,
      false /* include_output */);
  EXPECT_EQ(update_response.status(), grpc_api::ROUTINE_STATUS_ERROR);
  EXPECT_EQ(update_response.progress_percent(), 0);
  EXPECT_EQ(update_response.user_message(),
            grpc_api::ROUTINE_USER_MESSAGE_UNSET);
  EXPECT_EQ(update_response.output(), "");
  EXPECT_EQ(update_response.status_message(), "");
  EXPECT_EQ(update_response.service_status(),
            grpc_api::ROUTINE_SERVICE_STATUS_UNAVAILABLE);
}

// Test that the routine service can recover from an early gRPC request if
// wilco_dtc_supportd's mojo service is established later.
TEST_F(RoutineServiceTest, RecoverFromNoServiceRequest) {
  // Deal with a request sent before the mojo service is available.
  diagnostics_service()->SetMojoServiceIsAvailable(false);

  const auto unavailable_reply = ExecuteGetAvailableRoutines();
  EXPECT_EQ(unavailable_reply.routines_size(), 0);
  EXPECT_EQ(unavailable_reply.service_status(),
            grpc_api::ROUTINE_SERVICE_STATUS_UNAVAILABLE);
  base::RunLoop().RunUntilIdle();

  // Make the mojo service available, and make sure a valid response is
  // received.
  diagnostics_service()->SetMojoServiceIsAvailable(true);
  diagnostics_service()->SetGetAvailableRoutinesResponse(
      {mojo_ipc::DiagnosticRoutineEnum::kBatteryCapacity,
       mojo_ipc::DiagnosticRoutineEnum::kBatteryHealth,
       mojo_ipc::DiagnosticRoutineEnum::kSmartctlCheck,
       mojo_ipc::DiagnosticRoutineEnum::kUrandom,
       mojo_ipc::DiagnosticRoutineEnum::kCpuCache,
       mojo_ipc::DiagnosticRoutineEnum::kCpuStress,
       mojo_ipc::DiagnosticRoutineEnum::kFloatingPointAccuracy,
       mojo_ipc::DiagnosticRoutineEnum::kNvmeWearLevel,
       mojo_ipc::DiagnosticRoutineEnum::kNvmeSelfTest,
       mojo_ipc::DiagnosticRoutineEnum::kDiskRead});

  const auto reply = ExecuteGetAvailableRoutines();
  EXPECT_THAT(reply.routines(),
              ElementsAreArray(
                  {grpc_api::ROUTINE_BATTERY, grpc_api::ROUTINE_BATTERY_SYSFS,
                   grpc_api::ROUTINE_SMARTCTL_CHECK, grpc_api::ROUTINE_URANDOM,
                   grpc_api::ROUTINE_CPU_CACHE, grpc_api::ROUTINE_CPU_STRESS,
                   grpc_api::ROUTINE_FLOATING_POINT_ACCURACY,
                   grpc_api::ROUTINE_NVME_WEAR_LEVEL,
                   grpc_api::ROUTINE_NVME_SHORT_SELF_TEST,
                   grpc_api::ROUTINE_NVME_LONG_SELF_TEST,
                   grpc_api::ROUTINE_DISK_LINEAR_READ,
                   grpc_api::ROUTINE_DISK_RANDOM_READ}));
  EXPECT_EQ(reply.service_status(), grpc_api::ROUTINE_SERVICE_STATUS_OK);
}

// Test that the routine service handles a GetAvailableRoutines request sent
// when cros_healthd is unresponsive.
TEST_F(RoutineServiceTest, GetAvailableRoutinesUnresponsiveService) {
  diagnostics_service()->SetMojoServiceIsResponsive(false);

  const auto reply = ExecuteGetAvailableRoutines();
  EXPECT_EQ(reply.routines_size(), 0);
  EXPECT_EQ(reply.service_status(),
            grpc_api::ROUTINE_SERVICE_STATUS_UNAVAILABLE);
}

// Test that the routine service handles a RunRoutine request sent when
// cros_healthd is unresponsive.
TEST_F(RoutineServiceTest, RunRoutineUnresponsiveService) {
  diagnostics_service()->SetMojoServiceIsResponsive(false);

  const auto response = ExecuteRunRoutine(MakeSmartctlCheckRoutineRequest());
  EXPECT_EQ(response.status(), grpc_api::ROUTINE_STATUS_FAILED_TO_START);
  EXPECT_EQ(response.uuid(), 0);
  EXPECT_EQ(response.service_status(),
            grpc_api::ROUTINE_SERVICE_STATUS_UNAVAILABLE);
}

// Test that the routine service handles a GetRoutineUpdate request sent when
// cros_healthd is unresponsive.
TEST_F(RoutineServiceTest, GetRoutineUpdateUnresponsiveService) {
  diagnostics_service()->SetMojoServiceIsResponsive(false);

  constexpr int kUuid = 11;
  const auto update_response = ExecuteGetRoutineUpdate(
      kUuid, grpc_api::GetRoutineUpdateRequest::GET_STATUS,
      false /* include_output */);
  EXPECT_EQ(update_response.uuid(), kUuid);
  EXPECT_EQ(update_response.status(), grpc_api::ROUTINE_STATUS_ERROR);
  EXPECT_EQ(update_response.progress_percent(), 0);
  EXPECT_EQ(update_response.user_message(),
            grpc_api::ROUTINE_USER_MESSAGE_UNSET);
  EXPECT_EQ(update_response.output(), "");
  EXPECT_EQ(update_response.status_message(), "");
  EXPECT_EQ(update_response.service_status(),
            grpc_api::ROUTINE_SERVICE_STATUS_UNAVAILABLE);
}

// Test that the routine service can recover from a dropped connection.
TEST_F(RoutineServiceTest, RecoverFromDroppedConnection) {
  // Establish a valid connection.
  diagnostics_service()->SetGetAvailableRoutinesResponse(
      {mojo_ipc::DiagnosticRoutineEnum::kBatteryCapacity,
       mojo_ipc::DiagnosticRoutineEnum::kBatteryHealth,
       mojo_ipc::DiagnosticRoutineEnum::kSmartctlCheck,
       mojo_ipc::DiagnosticRoutineEnum::kUrandom,
       mojo_ipc::DiagnosticRoutineEnum::kCpuCache,
       mojo_ipc::DiagnosticRoutineEnum::kCpuStress,
       mojo_ipc::DiagnosticRoutineEnum::kFloatingPointAccuracy,
       mojo_ipc::DiagnosticRoutineEnum::kNvmeWearLevel,
       mojo_ipc::DiagnosticRoutineEnum::kNvmeSelfTest,
       mojo_ipc::DiagnosticRoutineEnum::kDiskRead});

  const auto reply = ExecuteGetAvailableRoutines();
  EXPECT_THAT(reply.routines(),
              ElementsAreArray(
                  {grpc_api::ROUTINE_BATTERY, grpc_api::ROUTINE_BATTERY_SYSFS,
                   grpc_api::ROUTINE_SMARTCTL_CHECK, grpc_api::ROUTINE_URANDOM,
                   grpc_api::ROUTINE_CPU_CACHE, grpc_api::ROUTINE_CPU_STRESS,
                   grpc_api::ROUTINE_FLOATING_POINT_ACCURACY,
                   grpc_api::ROUTINE_NVME_WEAR_LEVEL,
                   grpc_api::ROUTINE_NVME_SHORT_SELF_TEST,
                   grpc_api::ROUTINE_NVME_LONG_SELF_TEST,
                   grpc_api::ROUTINE_DISK_LINEAR_READ,
                   grpc_api::ROUTINE_DISK_RANDOM_READ}));
  EXPECT_EQ(reply.service_status(), grpc_api::ROUTINE_SERVICE_STATUS_OK);

  // Reset the connection, make cros_healthd unresponsive, and check to see that
  // the routine service responds appropriately.
  diagnostics_service()->ResetMojoConnection();
  diagnostics_service()->SetMojoServiceIsResponsive(false);

  const auto dropped_reply = ExecuteGetAvailableRoutines();
  EXPECT_EQ(dropped_reply.routines_size(), 0);
  EXPECT_EQ(dropped_reply.service_status(),
            grpc_api::ROUTINE_SERVICE_STATUS_UNAVAILABLE);

  // Set cros_healthd as available again, and make sure the routine service can
  // get valid responses.
  diagnostics_service()->SetMojoServiceIsResponsive(true);
  constexpr uint32_t kExpectedId = 77;
  diagnostics_service()->SetRunSomeRoutineResponse(
      kExpectedId, mojo_ipc::DiagnosticRoutineStatusEnum::kRunning);

  const auto reconnected_reply =
      ExecuteRunRoutine(MakeSmartctlCheckRoutineRequest());
  EXPECT_EQ(reconnected_reply.uuid(), kExpectedId);
  EXPECT_EQ(reconnected_reply.status(), grpc_api::ROUTINE_STATUS_RUNNING);
  EXPECT_EQ(reconnected_reply.service_status(),
            grpc_api::ROUTINE_SERVICE_STATUS_OK);
}

// Tests for the GetRoutineUpdate() method of RoutineService when an
// interactive update is returned.
//
// This is a parameterized test with the following parameters:
// * |mojo_message| - mojo's DiagnosticRoutineUserMessageEnum returned in the
//                    routine's update.
// * |grpc_message| - gRPC's DiagnosticRoutineUserMessage expected to be
//                    returned by the routine service.
class GetInteractiveUpdateTest
    : public RoutineServiceTest,
      public testing::WithParamInterface<
          std::tuple<mojo_ipc::DiagnosticRoutineUserMessageEnum,
                     grpc_api::DiagnosticRoutineUserMessage>> {
 protected:
  // Accessors to individual test parameters from the test parameter tuple
  // returned by gtest's GetParam():

  mojo_ipc::DiagnosticRoutineUserMessageEnum mojo_message() const {
    return std::get<0>(GetParam());
  }

  grpc_api::DiagnosticRoutineUserMessage grpc_message() const {
    return std::get<1>(GetParam());
  }
};

// Test that after a routine has started, we can access its interactive data.
TEST_P(GetInteractiveUpdateTest, AccessInteractiveRunningRoutine) {
  constexpr uint32_t kExpectedProgressPercent = 17;
  constexpr char kExpectedOutput[] = "Expected output.";
  diagnostics_service()->SetInteractiveUpdate(
      mojo_message(), kExpectedProgressPercent, kExpectedOutput);

  const auto update_response = ExecuteGetRoutineUpdate(
      0 /* uuid */, grpc_api::GetRoutineUpdateRequest::GET_STATUS,
      true /* include_output */);
  EXPECT_EQ(update_response.user_message(), grpc_message());
  EXPECT_EQ(update_response.progress_percent(), kExpectedProgressPercent);
  EXPECT_EQ(update_response.output(), kExpectedOutput);
  EXPECT_EQ(update_response.service_status(),
            grpc_api::ROUTINE_SERVICE_STATUS_OK);
}

INSTANTIATE_TEST_SUITE_P(
    ,
    GetInteractiveUpdateTest,
    testing::Values(std::make_tuple(
        mojo_ipc::DiagnosticRoutineUserMessageEnum::kUnplugACPower,
        grpc_api::ROUTINE_USER_MESSAGE_UNPLUG_AC_POWER)));

// Tests for the GetRoutineUpdate() method of RoutineService when a
// noninteractive update is returned.
//
// This is a parameterized test with the following parameters:
// * |mojo_status| - mojo's DiagnosticRoutineStatusEnum returned in the
//                   routine's update.
// * |grpc_status| - gRPC's DiagnosticRoutineStatus expected to be
//                   returned by the routine service.
class GetNonInteractiveUpdateTest
    : public RoutineServiceTest,
      public testing::WithParamInterface<
          std::tuple<mojo_ipc::DiagnosticRoutineStatusEnum,
                     grpc_api::DiagnosticRoutineStatus>> {
 protected:
  // Accessors to individual test parameters from the test parameter tuple
  // returned by gtest's GetParam():

  mojo_ipc::DiagnosticRoutineStatusEnum mojo_status() const {
    return std::get<0>(GetParam());
  }

  grpc_api::DiagnosticRoutineStatus grpc_status() const {
    return std::get<1>(GetParam());
  }
};

// Test that after a routine has started, we can access its noninteractive data.
TEST_P(GetNonInteractiveUpdateTest, AccessNonInteractiveRunningRoutine) {
  constexpr char kExpectedStatusMessage[] = "Expected status message.";
  constexpr uint32_t kExpectedProgressPercent = 18;
  constexpr char kExpectedOutput[] = "Expected output.";
  diagnostics_service()->SetNonInteractiveUpdate(
      mojo_status(), kExpectedStatusMessage, kExpectedProgressPercent,
      kExpectedOutput);

  const auto update_response = ExecuteGetRoutineUpdate(
      0 /* uuid */, grpc_api::GetRoutineUpdateRequest::GET_STATUS,
      true /* include_output */);
  EXPECT_EQ(update_response.status(), grpc_status());
  EXPECT_EQ(update_response.status_message(), kExpectedStatusMessage);
  EXPECT_EQ(update_response.progress_percent(), kExpectedProgressPercent);
  EXPECT_EQ(update_response.output(), kExpectedOutput);
  EXPECT_EQ(update_response.service_status(),
            grpc_api::ROUTINE_SERVICE_STATUS_OK);
}

INSTANTIATE_TEST_SUITE_P(
    ,
    GetNonInteractiveUpdateTest,
    testing::Values(
        std::make_tuple(mojo_ipc::DiagnosticRoutineStatusEnum::kReady,
                        grpc_api::ROUTINE_STATUS_READY),
        std::make_tuple(mojo_ipc::DiagnosticRoutineStatusEnum::kRunning,
                        grpc_api::ROUTINE_STATUS_RUNNING),
        std::make_tuple(mojo_ipc::DiagnosticRoutineStatusEnum::kWaiting,
                        grpc_api::ROUTINE_STATUS_WAITING),
        std::make_tuple(mojo_ipc::DiagnosticRoutineStatusEnum::kPassed,
                        grpc_api::ROUTINE_STATUS_PASSED),
        std::make_tuple(mojo_ipc::DiagnosticRoutineStatusEnum::kFailed,
                        grpc_api::ROUTINE_STATUS_FAILED),
        std::make_tuple(mojo_ipc::DiagnosticRoutineStatusEnum::kError,
                        grpc_api::ROUTINE_STATUS_ERROR),
        std::make_tuple(mojo_ipc::DiagnosticRoutineStatusEnum::kCancelled,
                        grpc_api::ROUTINE_STATUS_CANCELLED),
        std::make_tuple(mojo_ipc::DiagnosticRoutineStatusEnum::kFailedToStart,
                        grpc_api::ROUTINE_STATUS_FAILED_TO_START),
        std::make_tuple(mojo_ipc::DiagnosticRoutineStatusEnum::kRemoved,
                        grpc_api::ROUTINE_STATUS_REMOVED),
        std::make_tuple(mojo_ipc::DiagnosticRoutineStatusEnum::kCancelling,
                        grpc_api::ROUTINE_STATUS_CANCELLING)));

// Tests for the GetRoutineUpdate() method of RoutineService with different
// commands.
//
// This is a parameterized test with the following parameters:
// * |command| - gRPC's GetRoutineUpdateRequest::Command included in the
//               GetRoutineUpdateRequest.
class GetRoutineUpdateCommandTest
    : public RoutineServiceTest,
      public testing::WithParamInterface<
          grpc_api::GetRoutineUpdateRequest::Command> {
 protected:
  // Accessors to the test parameter returned by gtest's GetParam():

  grpc_api::GetRoutineUpdateRequest::Command command() const {
    return GetParam();
  }
};

// Test that we can send the given command.
TEST_P(GetRoutineUpdateCommandTest, SendCommand) {
  constexpr char kExpectedStatusMessage[] = "Expected status message.";
  constexpr uint32_t kExpectedProgressPercent = 19;
  constexpr char kExpectedOutput[] = "Expected output.";
  constexpr mojo_ipc::DiagnosticRoutineStatusEnum kMojoStatus =
      mojo_ipc::DiagnosticRoutineStatusEnum::kRunning;
  constexpr grpc_api::DiagnosticRoutineStatus kExpectedStatus =
      grpc_api::ROUTINE_STATUS_RUNNING;
  diagnostics_service()->SetNonInteractiveUpdate(
      kMojoStatus, kExpectedStatusMessage, kExpectedProgressPercent,
      kExpectedOutput);

  const auto update_response = ExecuteGetRoutineUpdate(
      0 /* uuid */, command(), true /* include_output */);
  EXPECT_EQ(update_response.status(), kExpectedStatus);
  EXPECT_EQ(update_response.status_message(), kExpectedStatusMessage);
  EXPECT_EQ(update_response.progress_percent(), kExpectedProgressPercent);
  EXPECT_EQ(update_response.output(), kExpectedOutput);
  EXPECT_EQ(update_response.service_status(),
            grpc_api::ROUTINE_SERVICE_STATUS_OK);
}

INSTANTIATE_TEST_SUITE_P(
    ,
    GetRoutineUpdateCommandTest,
    testing::Values(grpc_api::GetRoutineUpdateRequest::RESUME,
                    grpc_api::GetRoutineUpdateRequest::CANCEL,
                    grpc_api::GetRoutineUpdateRequest::REMOVE,
                    grpc_api::GetRoutineUpdateRequest::GET_STATUS));

// Tests for the RunRoutine() method of RoutineService with different requests.
//
// This is a parameterized test with the following parameters:
// * |request| - gRPC's RunRoutineRequest to be requested.
class RunRoutineTest
    : public RoutineServiceTest,
      public testing::WithParamInterface<grpc_api::RunRoutineRequest> {
 public:
  RunRoutineTest() = default;

  // Accessors to the test parameter returned by gtest's GetParam():

  grpc_api::RunRoutineRequest request() const { return GetParam(); }

 private:
  DISALLOW_COPY_AND_ASSIGN(RunRoutineTest);
};

// Test that we can request that the given routine is run.
TEST_P(RunRoutineTest, RunRoutine) {
  constexpr uint32_t kExpectedId = 77;
  diagnostics_service()->SetRunSomeRoutineResponse(
      kExpectedId, mojo_ipc::DiagnosticRoutineStatusEnum::kRunning);

  const auto reply = ExecuteRunRoutine(request());
  EXPECT_EQ(reply.uuid(), kExpectedId);
  EXPECT_EQ(reply.status(), grpc_api::ROUTINE_STATUS_RUNNING);
  EXPECT_EQ(reply.service_status(), grpc_api::ROUTINE_SERVICE_STATUS_OK);
}

INSTANTIATE_TEST_SUITE_P(
    ,
    RunRoutineTest,
    testing::Values(MakeBatteryRoutineRequest(),
                    MakeDefaultBatteryRoutineRequest(),
                    MakeBatterySysfsRoutineRequest(),
                    MakeUrandomRoutineRequest(),
                    MakeSmartctlCheckRoutineRequest(),
                    MakeCpuCacheRoutineRequest(),
                    MakeCpuStressRoutineRequest(),
                    MakeFloatingPointAccuracyRoutineRequest(),
                    MakeNvmeWearLevelRoutineRequest(),
                    MakeNvmeSelfTestShortRoutineRequest(),
                    MakeNvmeSelfTestLongRoutineRequest(),
                    MakeDiskLinearReadRoutineRequest(),
                    MakeDiskRandomReadRoutineRequest()));

}  // namespace

}  // namespace diagnostics
