blob: 2f1f9f997eb02bf871119dbb33a3296572854b79 [file] [log] [blame]
// Copyright 2018 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <cstdint>
#include <iterator>
#include <memory>
#include <string>
#include <tuple>
#include <utility>
#include <vector>
#include <base/bind.h>
#include <base/callback.h>
#include <base/files/file_path.h>
#include <base/files/scoped_temp_dir.h>
#include <base/optional.h>
#include <base/run_loop.h>
#include <base/strings/string_piece.h>
#include <base/strings/stringprintf.h>
#include <base/system/sys_info.h>
#include <base/test/task_environment.h>
#include <base/time/time.h>
#include <gmock/gmock.h>
#include <google/protobuf/repeated_field.h>
#include <gtest/gtest.h>
#include "diagnostics/common/file_test_utils.h"
#include "diagnostics/common/protobuf_test_utils.h"
#include "diagnostics/wilco_dtc_supportd/ec_constants.h"
#include "diagnostics/wilco_dtc_supportd/grpc_service.h"
#include "diagnostics/wilco_dtc_supportd/telemetry/mock_system_files_service.h"
#include "diagnostics/wilco_dtc_supportd/telemetry/mock_system_info_service.h"
#include "mojo/cros_healthd_probe.mojom.h"
#include "wilco_dtc_supportd.pb.h" // NOLINT(build/include)
using testing::_;
using testing::AnyOf;
using testing::ByMove;
using testing::ByRef;
using testing::DoAll;
using testing::Eq;
using testing::Invoke;
using testing::NotNull;
using testing::Return;
using testing::SetArgPointee;
using testing::StrEq;
using testing::StrictMock;
using testing::UnorderedElementsAre;
using testing::WithArgs;
namespace diagnostics {
namespace {
using DelegateWebRequestHttpMethod =
GrpcService::Delegate::WebRequestHttpMethod;
using DelegateWebRequestStatus = GrpcService::Delegate::WebRequestStatus;
using DelegateDriveSystemDataType = GrpcService::Delegate::DriveSystemDataType;
constexpr char kFakeFileContentsChars[] = "\0fake Æ row 1\nfake row 2\n\0\377";
constexpr int kHttpStatusOk = 200;
constexpr char kBadNonHttpsUrl[] = "Http://www.google.com";
constexpr char kCorrectUrl[] = "hTTps://www.google.com";
constexpr char kFakeWebResponseBody[] = "\0Fake WEB\n response body\n\0";
const DelegateWebRequestHttpMethod kDelegateWebRequestHttpMethodGet =
DelegateWebRequestHttpMethod::kGet;
const DelegateWebRequestHttpMethod kDelegateWebRequestHttpMethodHead =
DelegateWebRequestHttpMethod::kHead;
const DelegateWebRequestHttpMethod kDelegateWebRequestHttpMethodPost =
DelegateWebRequestHttpMethod::kPost;
const DelegateWebRequestHttpMethod kDelegateWebRequestHttpMethodPut =
DelegateWebRequestHttpMethod::kPut;
const DelegateWebRequestHttpMethod kDelegateWebRequestHttpMethodPatch =
DelegateWebRequestHttpMethod::kPatch;
constexpr grpc_api::DiagnosticRoutine kFakeAvailableRoutines[] = {
grpc_api::ROUTINE_BATTERY,
grpc_api::ROUTINE_BATTERY_SYSFS,
grpc_api::ROUTINE_SMARTCTL_CHECK,
grpc_api::ROUTINE_URANDOM,
grpc_api::ROUTINE_FLOATING_POINT_ACCURACY,
grpc_api::ROUTINE_NVME_SHORT_SELF_TEST,
grpc_api::ROUTINE_NVME_LONG_SELF_TEST};
constexpr int kFakeUuid = 13;
constexpr grpc_api::DiagnosticRoutineStatus kFakeStatus =
grpc_api::ROUTINE_STATUS_RUNNING;
constexpr int kFakeProgressPercent = 37;
constexpr grpc_api::DiagnosticRoutineUserMessage kFakeUserMessage =
grpc_api::ROUTINE_USER_MESSAGE_UNSET;
constexpr char kFakeOutput[] = "Some output.";
constexpr char kFakeStatusMessage[] = "Status message.";
constexpr char kTestFilePath[] = "file/path";
constexpr char kTestCanonicalFilePath[] = "canonical/path";
std::string FakeFileContents() {
return std::string(std::begin(kFakeFileContentsChars),
std::end(kFakeFileContentsChars));
}
template <class T>
base::Callback<void(grpc::Status, std::unique_ptr<T>)>
GrpcCallbackResponseSaver(std::unique_ptr<T>* response) {
return base::Bind(
[](std::unique_ptr<T>* response, grpc::Status status,
std::unique_ptr<T> received_response) {
*response = std::move(received_response);
ASSERT_TRUE(*response);
},
base::Unretained(response));
}
std::unique_ptr<grpc_api::GetEcTelemetryResponse> MakeGetEcTelemetryResponse(
grpc_api::GetEcTelemetryResponse::Status status,
const std::string& payload) {
auto response = std::make_unique<grpc_api::GetEcTelemetryResponse>();
response->set_status(status);
response->set_payload(payload);
return response;
}
std::unique_ptr<grpc_api::PerformWebRequestResponse>
MakePerformWebRequestResponse(
grpc_api::PerformWebRequestResponse::Status status,
const int* http_status,
const char* response_body) {
auto response = std::make_unique<grpc_api::PerformWebRequestResponse>();
response->set_status(status);
if (http_status)
response->set_http_status(*http_status);
if (response_body)
response->set_response_body(response_body);
return response;
}
std::unique_ptr<grpc_api::GetAvailableRoutinesResponse>
MakeGetAvailableRoutinesResponse() {
auto response = std::make_unique<grpc_api::GetAvailableRoutinesResponse>();
for (auto routine : kFakeAvailableRoutines)
response->add_routines(routine);
response->set_service_status(grpc_api::ROUTINE_SERVICE_STATUS_OK);
return response;
}
std::unique_ptr<grpc_api::RunRoutineResponse> MakeRunRoutineResponse() {
auto response = std::make_unique<grpc_api::RunRoutineResponse>();
response->set_uuid(kFakeUuid);
response->set_status(kFakeStatus);
response->set_service_status(grpc_api::ROUTINE_SERVICE_STATUS_OK);
return response;
}
std::unique_ptr<grpc_api::GetRoutineUpdateResponse>
MakeGetRoutineUpdateResponse(int uuid, bool include_output) {
auto response = std::make_unique<grpc_api::GetRoutineUpdateResponse>();
response->set_uuid(uuid);
response->set_status(kFakeStatus);
response->set_progress_percent(kFakeProgressPercent);
response->set_user_message(kFakeUserMessage);
response->set_output(include_output ? kFakeOutput : "");
response->set_status_message(kFakeStatusMessage);
response->set_service_status(grpc_api::ROUTINE_SERVICE_STATUS_OK);
return response;
}
std::unique_ptr<grpc_api::RunRoutineRequest> MakeRunBatteryRoutineRequest() {
constexpr int kLowmAh = 10;
constexpr int kHighmAh = 100;
auto request = std::make_unique<grpc_api::RunRoutineRequest>();
request->set_routine(grpc_api::ROUTINE_BATTERY);
request->mutable_battery_params()->set_low_mah(kLowmAh);
request->mutable_battery_params()->set_high_mah(kHighmAh);
return request;
}
std::unique_ptr<grpc_api::RunRoutineRequest>
MakeRunBatterySysfsRoutineRequest() {
constexpr int kMaximumCycleCount = 5;
constexpr int kPercentBatteryWearAllowed = 10;
auto request = std::make_unique<grpc_api::RunRoutineRequest>();
request->set_routine(grpc_api::ROUTINE_BATTERY_SYSFS);
request->mutable_battery_sysfs_params()->set_maximum_cycle_count(
kMaximumCycleCount);
request->mutable_battery_sysfs_params()->set_percent_battery_wear_allowed(
kPercentBatteryWearAllowed);
return request;
}
std::unique_ptr<grpc_api::RunRoutineRequest> MakeRunUrandomRoutineRequest() {
constexpr int kLengthSeconds = 10;
auto request = std::make_unique<grpc_api::RunRoutineRequest>();
request->set_routine(grpc_api::ROUTINE_URANDOM);
request->mutable_urandom_params()->set_length_seconds(kLengthSeconds);
return request;
}
std::unique_ptr<grpc_api::RunRoutineRequest>
MakeRunFloatingPointAccuracyRoutineRequest() {
constexpr int kLengthSeconds = 10;
auto request = std::make_unique<grpc_api::RunRoutineRequest>();
request->set_routine(grpc_api::ROUTINE_FLOATING_POINT_ACCURACY);
request->mutable_floating_point_accuracy_params()->set_length_seconds(
kLengthSeconds);
return request;
}
std::unique_ptr<grpc_api::RunRoutineRequest>
MakeRunNvmeWearLevelRoutineRequest() {
constexpr int kWearLevelThreshold = 50;
auto request = std::make_unique<grpc_api::RunRoutineRequest>();
request->set_routine(grpc_api::ROUTINE_NVME_WEAR_LEVEL);
request->mutable_nvme_wear_level_params()->set_wear_level_threshold(
kWearLevelThreshold);
return request;
}
std::unique_ptr<grpc_api::RunRoutineRequest>
MakeRunNvmeShortSelfTestRoutineRequest() {
auto request = std::make_unique<grpc_api::RunRoutineRequest>();
request->set_routine(grpc_api::ROUTINE_NVME_SHORT_SELF_TEST);
request->mutable_nvme_short_self_test_params();
return request;
}
std::unique_ptr<grpc_api::RunRoutineRequest>
MakeRunNvmeLongSelfTestRoutineRequest() {
auto request = std::make_unique<grpc_api::RunRoutineRequest>();
request->set_routine(grpc_api::ROUTINE_NVME_LONG_SELF_TEST);
request->mutable_nvme_long_self_test_params();
return request;
}
std::unique_ptr<grpc_api::RunRoutineRequest>
MakeRunPrimeSearchRoutineRequest() {
constexpr int kLengthSeconds = 10;
constexpr int kMaxNum = 1000000;
auto request = std::make_unique<grpc_api::RunRoutineRequest>();
request->set_routine(grpc_api::ROUTINE_PRIME_SEARCH);
request->mutable_prime_search_params()->set_length_seconds(kLengthSeconds);
request->mutable_prime_search_params()->set_max_num(kMaxNum);
return request;
}
MATCHER_P(GrpcDumpsEquivalentWithInternal, expected, "") {
if (arg.size() != expected.get().size())
return false;
for (int i = 0; i < arg.size(); i++) {
if (arg[i].contents() != expected.get()[i]->contents ||
arg[i].canonical_path() != expected.get()[i]->canonical_path.value() ||
arg[i].path() != expected.get()[i]->path.value())
return false;
}
return true;
}
class MockGrpcServiceDelegate : public GrpcService::Delegate {
public:
// GrpcService::Delegate overrides:
MOCK_METHOD(void,
SendWilcoDtcMessageToUi,
(const std::string&, const SendMessageToUiCallback&),
(override));
MOCK_METHOD(void,
PerformWebRequestToBrowser,
(WebRequestHttpMethod,
const std::string&,
const std::vector<std::string>&,
const std::string&,
const PerformWebRequestToBrowserCallback&),
(override));
MOCK_METHOD(void,
GetAvailableRoutinesToService,
(const GetAvailableRoutinesToServiceCallback&),
(override));
MOCK_METHOD(void,
RunRoutineToService,
(const grpc_api::RunRoutineRequest&,
const RunRoutineToServiceCallback&),
(override));
MOCK_METHOD(void,
GetRoutineUpdateRequestToService,
(const int,
const grpc_api::GetRoutineUpdateRequest::Command,
const bool,
const GetRoutineUpdateRequestToServiceCallback&),
(override));
MOCK_METHOD(void,
GetConfigurationDataFromBrowser,
(const GetConfigurationDataFromBrowserCallback&),
(override));
MOCK_METHOD(void,
GetDriveSystemData,
(DriveSystemDataType, const GetDriveSystemDataCallback&),
(override));
MOCK_METHOD(void, RequestBluetoothDataNotification, (), (override));
MOCK_METHOD(
void,
ProbeTelemetryInfo,
(std::vector<chromeos::cros_healthd::mojom::ProbeCategoryEnum> categories,
ProbeTelemetryInfoCallback callback),
(override));
EcService* GetEcService() override { return ec_service_.get(); }
private:
std::unique_ptr<EcService> ec_service_ = std::make_unique<EcService>();
};
// Tests for the GrpcService class.
class GrpcServiceTest : public testing::Test {
protected:
GrpcServiceTest() = default;
void SetUp() override {
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
service_.set_root_dir_for_testing(temp_dir_.GetPath());
delegate_.GetEcService()->set_root_dir_for_testing(temp_dir_.GetPath());
}
GrpcService* service() { return &service_; }
StrictMock<MockGrpcServiceDelegate>* delegate() { return &delegate_; }
void ExecuteSendMessageToUi(
const std::string& json_message,
std::unique_ptr<grpc_api::SendMessageToUiResponse>* response) {
auto request = std::make_unique<grpc_api::SendMessageToUiRequest>();
request->set_json_message(json_message);
EXPECT_CALL(delegate_, SendWilcoDtcMessageToUi(json_message, _))
.WillOnce(WithArgs<1>(Invoke(
[json_message](const base::Callback<void(
grpc::Status, base::StringPiece)>& callback) {
callback.Run(grpc::Status::OK, json_message);
})));
service()->SendMessageToUi(std::move(request),
GrpcCallbackResponseSaver(response));
}
void ExecuteGetProcData(grpc_api::GetProcDataRequest::Type request_type,
std::vector<grpc_api::FileDump>* file_dumps) {
auto request = std::make_unique<grpc_api::GetProcDataRequest>();
request->set_type(request_type);
std::unique_ptr<grpc_api::GetProcDataResponse> response;
service()->GetProcData(std::move(request),
GrpcCallbackResponseSaver(&response));
// Expect the method to return immediately.
ASSERT_TRUE(response);
file_dumps->assign(response->file_dump().begin(),
response->file_dump().end());
}
void ExecuteGetSysfsData(grpc_api::GetSysfsDataRequest::Type request_type,
std::vector<grpc_api::FileDump>* file_dumps) {
auto request = std::make_unique<grpc_api::GetSysfsDataRequest>();
request->set_type(request_type);
std::unique_ptr<grpc_api::GetSysfsDataResponse> response;
service()->GetSysfsData(std::move(request),
GrpcCallbackResponseSaver(&response));
// Expect the method to return immediately.
ASSERT_TRUE(response);
file_dumps->assign(response->file_dump().begin(),
response->file_dump().end());
}
void ExecuteGetEcTelemetry(
const std::string request_payload,
std::unique_ptr<grpc_api::GetEcTelemetryResponse>* response) {
auto request = std::make_unique<grpc_api::GetEcTelemetryRequest>();
request->set_payload(request_payload);
service()->GetEcTelemetry(std::move(request),
GrpcCallbackResponseSaver(response));
ASSERT_TRUE(*response);
}
void ExecutePerformWebRequest(
grpc_api::PerformWebRequestParameter::HttpMethod http_method,
const std::string& url,
const std::vector<std::string>& string_headers,
const std::string& request_body,
const DelegateWebRequestHttpMethod* delegate_http_method,
std::unique_ptr<grpc_api::PerformWebRequestResponse>* response) {
auto request = std::make_unique<grpc_api::PerformWebRequestParameter>();
request->set_http_method(http_method);
request->set_url(url);
google::protobuf::RepeatedPtrField<std::string> headers(
string_headers.begin(), string_headers.end());
request->mutable_headers()->Swap(&headers);
request->set_request_body(request_body);
base::Callback<void(DelegateWebRequestStatus, int)> callback;
if (delegate_http_method) {
EXPECT_CALL(delegate_,
PerformWebRequestToBrowser(Eq(*delegate_http_method), url,
string_headers, request_body, _))
.WillOnce(WithArgs<4>(Invoke(
[](const base::Callback<void(DelegateWebRequestStatus, int,
base::StringPiece)>& callback) {
callback.Run(DelegateWebRequestStatus::kOk, kHttpStatusOk,
kFakeWebResponseBody);
})));
}
service()->PerformWebRequest(std::move(request),
GrpcCallbackResponseSaver(response));
}
void ExecuteGetAvailableRoutines(
std::unique_ptr<grpc_api::GetAvailableRoutinesResponse>* response) {
auto request = std::make_unique<grpc_api::GetAvailableRoutinesRequest>();
EXPECT_CALL(delegate_, GetAvailableRoutinesToService(_))
.WillOnce(Invoke([](const base::Callback<void(
const std::vector<grpc_api::DiagnosticRoutine>&,
grpc_api::RoutineServiceStatus)>& callback) {
callback.Run(std::vector<grpc_api::DiagnosticRoutine>(
std::begin(kFakeAvailableRoutines),
std::end(kFakeAvailableRoutines)),
grpc_api::ROUTINE_SERVICE_STATUS_OK);
}));
service()->GetAvailableRoutines(std::move(request),
GrpcCallbackResponseSaver(response));
}
void ExecuteRunRoutine(
std::unique_ptr<grpc_api::RunRoutineRequest> request,
std::unique_ptr<grpc_api::RunRoutineResponse>* response,
bool is_valid_request) {
if (is_valid_request) {
EXPECT_CALL(delegate_, RunRoutineToService(_, _))
.WillOnce(WithArgs<1>(
Invoke([](const base::Callback<void(
int, grpc_api::DiagnosticRoutineStatus,
grpc_api::RoutineServiceStatus)>& callback) {
callback.Run(kFakeUuid, kFakeStatus,
grpc_api::ROUTINE_SERVICE_STATUS_OK);
})));
}
service()->RunRoutine(std::move(request),
GrpcCallbackResponseSaver(response));
}
void ExecuteGetRoutineUpdate(
int uuid,
grpc_api::GetRoutineUpdateRequest::Command command,
bool include_output,
std::unique_ptr<grpc_api::GetRoutineUpdateResponse>* response) {
if (command != grpc_api::GetRoutineUpdateRequest::COMMAND_UNSET) {
EXPECT_CALL(delegate_, GetRoutineUpdateRequestToService(
uuid, command, include_output, _))
.WillOnce(WithArgs<3>(
Invoke([=](const base::Callback<void(
int, grpc_api::DiagnosticRoutineStatus, int,
grpc_api::DiagnosticRoutineUserMessage,
const std::string&, const std::string&,
grpc_api::RoutineServiceStatus)>& callback) {
callback.Run(
uuid, kFakeStatus, kFakeProgressPercent, kFakeUserMessage,
include_output ? kFakeOutput : "", kFakeStatusMessage,
grpc_api::ROUTINE_SERVICE_STATUS_OK);
})));
}
auto request = std::make_unique<grpc_api::GetRoutineUpdateRequest>();
request->set_uuid(uuid);
request->set_command(command);
request->set_include_output(include_output);
service()->GetRoutineUpdate(std::move(request),
GrpcCallbackResponseSaver(response));
}
void ExecuteGetConfigurationData(
const std::string& json_configuration_data,
std::unique_ptr<grpc_api::GetConfigurationDataResponse>* response) {
auto request = std::make_unique<grpc_api::GetConfigurationDataRequest>();
EXPECT_CALL(delegate_, GetConfigurationDataFromBrowser(_))
.WillOnce(WithArgs<0>(Invoke(
[json_configuration_data](
const base::Callback<void(const std::string&)>& callback) {
callback.Run(json_configuration_data);
})));
service()->GetConfigurationData(std::move(request),
GrpcCallbackResponseSaver(response));
}
void ExecuteGetVpdField(grpc_api::GetVpdFieldRequest::VpdField vpd_field,
grpc_api::GetVpdFieldResponse::Status* status,
std::string* vpd_field_value) {
auto request = std::make_unique<grpc_api::GetVpdFieldRequest>();
request->set_vpd_field(vpd_field);
std::unique_ptr<grpc_api::GetVpdFieldResponse> response;
service()->GetVpdField(std::move(request),
GrpcCallbackResponseSaver(&response));
// Expect the method to return immediately.
ASSERT_TRUE(response);
*status = response->status();
*vpd_field_value = response->vpd_field_value();
}
grpc_api::FileDump MakeFileDump(
const base::FilePath& relative_file_path,
const base::FilePath& canonical_relative_file_path,
const std::string& file_contents) const {
grpc_api::FileDump file_dump;
file_dump.set_path(temp_dir_.GetPath().Append(relative_file_path).value());
file_dump.set_canonical_path(
temp_dir_.GetPath().Append(canonical_relative_file_path).value());
file_dump.set_contents(file_contents);
return file_dump;
}
base::FilePath temp_dir_path() const { return temp_dir_.GetPath(); }
private:
base::test::TaskEnvironment task_environment_{
base::test::TaskEnvironment::ThreadingMode::MAIN_THREAD_ONLY};
base::ScopedTempDir temp_dir_;
StrictMock<MockGrpcServiceDelegate> delegate_;
GrpcService service_{&delegate_};
};
TEST_F(GrpcServiceTest, SendMessageToUi) {
constexpr char kFakeJsonMessage[] = "Fake Message From Wilco DTC to UI";
std::unique_ptr<grpc_api::SendMessageToUiResponse> response;
ExecuteSendMessageToUi(kFakeJsonMessage, &response);
ASSERT_TRUE(response);
EXPECT_EQ(response->response_json_message(), kFakeJsonMessage);
}
TEST_F(GrpcServiceTest, GetProcDataUnsetType) {
std::vector<grpc_api::FileDump> file_dumps;
ExecuteGetProcData(grpc_api::GetProcDataRequest::TYPE_UNSET, &file_dumps);
EXPECT_TRUE(file_dumps.empty())
<< "Obtained: "
<< GetProtosRangeDebugString(file_dumps.begin(), file_dumps.end());
}
TEST_F(GrpcServiceTest, GetSysfsDataUnsetType) {
std::vector<grpc_api::FileDump> file_dumps;
ExecuteGetSysfsData(grpc_api::GetSysfsDataRequest::TYPE_UNSET, &file_dumps);
EXPECT_TRUE(file_dumps.empty())
<< "Obtained: "
<< GetProtosRangeDebugString(file_dumps.begin(), file_dumps.end());
}
TEST_F(GrpcServiceTest, RunRoutineUnsetType) {
auto request = std::make_unique<grpc_api::RunRoutineRequest>();
request->set_routine(grpc_api::ROUTINE_UNSET);
auto response = std::make_unique<grpc_api::RunRoutineResponse>();
ExecuteRunRoutine(std::move(request), &response,
false /* is_valid_request */);
EXPECT_EQ(response->uuid(), 0);
EXPECT_EQ(response->status(), grpc_api::ROUTINE_STATUS_INVALID_FIELD);
}
TEST_F(GrpcServiceTest, GetRoutineUpdateUnsetType) {
std::unique_ptr<grpc_api::GetRoutineUpdateResponse> response;
constexpr bool kIncludeOutput = false;
ExecuteGetRoutineUpdate(kFakeUuid,
grpc_api::GetRoutineUpdateRequest::COMMAND_UNSET,
kIncludeOutput, &response);
ASSERT_TRUE(response);
EXPECT_EQ(response->uuid(), kFakeUuid);
EXPECT_EQ(response->status(), grpc_api::ROUTINE_STATUS_INVALID_FIELD);
}
// Test that GetEcTelemetry() response contains expected |status| and |payload|
// field values.
TEST_F(GrpcServiceTest, GetEcTelemetryErrorAccessingDriver) {
std::unique_ptr<grpc_api::GetEcTelemetryResponse> response;
ExecuteGetEcTelemetry(FakeFileContents(), &response);
ASSERT_TRUE(response);
auto expected_response = MakeGetEcTelemetryResponse(
grpc_api::GetEcTelemetryResponse::STATUS_ERROR_ACCESSING_DRIVER, "");
EXPECT_THAT(*response, ProtobufEquals(*expected_response))
<< "Actual response: {" << response->ShortDebugString() << "}";
}
// Test that GetAvailableRoutines returns the expected list of diagnostic
// routines.
TEST_F(GrpcServiceTest, GetAvailableRoutines) {
std::unique_ptr<grpc_api::GetAvailableRoutinesResponse> response;
ExecuteGetAvailableRoutines(&response);
auto expected_response = MakeGetAvailableRoutinesResponse();
EXPECT_THAT(*response, ProtobufEquals(*expected_response))
<< "Actual response: {" << response->ShortDebugString() << "}";
}
// Test that we can request that the battery routine be run.
TEST_F(GrpcServiceTest, RunBatteryRoutine) {
std::unique_ptr<grpc_api::RunRoutineResponse> response;
ExecuteRunRoutine(MakeRunBatteryRoutineRequest(), &response,
true /* is_valid_request */);
auto expected_response = MakeRunRoutineResponse();
EXPECT_THAT(*response, ProtobufEquals(*expected_response))
<< "Actual response: {" << response->ShortDebugString() << "}";
}
// Test that a battery routine with no parameters will fail.
TEST_F(GrpcServiceTest, RunBatteryRoutineNoParameters) {
std::unique_ptr<grpc_api::RunRoutineResponse> response;
auto request = std::make_unique<grpc_api::RunRoutineRequest>();
request->set_routine(grpc_api::ROUTINE_BATTERY);
ExecuteRunRoutine(std::move(request), &response,
false /* is_valid_request */);
EXPECT_EQ(response->uuid(), 0);
EXPECT_EQ(response->status(), grpc_api::ROUTINE_STATUS_INVALID_FIELD);
}
// Test that we can request that the battery_sysfs routine be run.
TEST_F(GrpcServiceTest, RunBatterySysfsRoutine) {
std::unique_ptr<grpc_api::RunRoutineResponse> response;
ExecuteRunRoutine(MakeRunBatterySysfsRoutineRequest(), &response,
true /* is_valid_request */);
auto expected_response = MakeRunRoutineResponse();
EXPECT_THAT(*response, ProtobufEquals(*expected_response))
<< "Actual response: {" << response->ShortDebugString() << "}";
}
// Test that a battery_sysfs routine with no parameters will fail.
TEST_F(GrpcServiceTest, RunBatterySysfsRoutineNoParameters) {
std::unique_ptr<grpc_api::RunRoutineResponse> response;
auto request = std::make_unique<grpc_api::RunRoutineRequest>();
request->set_routine(grpc_api::ROUTINE_BATTERY_SYSFS);
ExecuteRunRoutine(std::move(request), &response,
false /* is_valid_request */);
EXPECT_EQ(response->uuid(), 0);
EXPECT_EQ(response->status(), grpc_api::ROUTINE_STATUS_INVALID_FIELD);
}
// Test that we can request that the urandom routine be run.
TEST_F(GrpcServiceTest, RunUrandomRoutine) {
std::unique_ptr<grpc_api::RunRoutineResponse> response;
ExecuteRunRoutine(MakeRunUrandomRoutineRequest(), &response,
true /* is_valid_request */);
auto expected_response = MakeRunRoutineResponse();
EXPECT_THAT(*response, ProtobufEquals(*expected_response))
<< "Actual response: {" << response->ShortDebugString() << "}";
}
// Test that a urandom routine with no parameters will fail.
TEST_F(GrpcServiceTest, RunUrandomRoutineNoParameters) {
std::unique_ptr<grpc_api::RunRoutineResponse> response;
auto request = std::make_unique<grpc_api::RunRoutineRequest>();
request->set_routine(grpc_api::ROUTINE_URANDOM);
ExecuteRunRoutine(std::move(request), &response,
false /* is_valid_request */);
EXPECT_EQ(response->uuid(), 0);
EXPECT_EQ(response->status(), grpc_api::ROUTINE_STATUS_INVALID_FIELD);
}
// Test that we can request that the floating_point_accuracy routine be run.
TEST_F(GrpcServiceTest, RunFloatingPointAccuracyRoutine) {
std::unique_ptr<grpc_api::RunRoutineResponse> response;
ExecuteRunRoutine(MakeRunFloatingPointAccuracyRoutineRequest(), &response,
true /* is_valid_request */);
auto expected_response = MakeRunRoutineResponse();
EXPECT_THAT(*response, ProtobufEquals(*expected_response))
<< "Actual response: {" << response->ShortDebugString() << "}";
}
// Test that we can request that the prime search routine be run.
TEST_F(GrpcServiceTest, RunPrimeSearchRoutine) {
std::unique_ptr<grpc_api::RunRoutineResponse> response;
ExecuteRunRoutine(MakeRunPrimeSearchRoutineRequest(), &response,
true /* is_valid_request */);
auto expected_response = MakeRunRoutineResponse();
EXPECT_THAT(*response, ProtobufEquals(*expected_response))
<< "Actual response: {" << response->ShortDebugString() << "}";
}
// Test that we can request that the nvme_wear_level routine be run.
TEST_F(GrpcServiceTest, RunNvmeWearLevelRoutine) {
std::unique_ptr<grpc_api::RunRoutineResponse> response;
ExecuteRunRoutine(MakeRunNvmeWearLevelRoutineRequest(), &response,
true /* is_valid_request */);
auto expected_response = MakeRunRoutineResponse();
EXPECT_THAT(*response, ProtobufEquals(*expected_response))
<< "Actual response: {" << response->ShortDebugString() << "}";
}
// Test that a nvme_wear_level routine with no parameters will fail.
TEST_F(GrpcServiceTest, RunNvmeWearLevelRoutineNoParameters) {
std::unique_ptr<grpc_api::RunRoutineResponse> response;
auto request = std::make_unique<grpc_api::RunRoutineRequest>();
request->set_routine(grpc_api::ROUTINE_NVME_WEAR_LEVEL);
ExecuteRunRoutine(std::move(request), &response,
false /* is_valid_request */);
EXPECT_EQ(response->uuid(), 0);
EXPECT_EQ(response->status(), grpc_api::ROUTINE_STATUS_INVALID_FIELD);
}
// Test that we can request that the nvme_self_test routine for short time be
// run.
TEST_F(GrpcServiceTest, RunNvmeSelfTestShortRoutine) {
std::unique_ptr<grpc_api::RunRoutineResponse> response;
ExecuteRunRoutine(MakeRunNvmeShortSelfTestRoutineRequest(), &response,
true /* is_valid_request */);
auto expected_response = MakeRunRoutineResponse();
EXPECT_THAT(*response, ProtobufEquals(*expected_response))
<< "Actual response: {" << response->ShortDebugString() << "}";
}
// Test that linear read routine can be run.
TEST_F(GrpcServiceTest, RunDiskLinearReadRoutine) {
std::unique_ptr<grpc_api::RunRoutineResponse> response;
auto request = std::make_unique<grpc_api::RunRoutineRequest>();
request->set_routine(grpc_api::ROUTINE_DISK_LINEAR_READ);
request->mutable_disk_linear_read_params()->set_length_seconds(10);
request->mutable_disk_linear_read_params()->set_file_size_mb(1024);
ExecuteRunRoutine(std::move(request), &response, true /* is_valid_request */);
auto expected_response = MakeRunRoutineResponse();
EXPECT_THAT(*response, ProtobufEquals(*expected_response))
<< "Actual response: {" << response->ShortDebugString() << "}";
}
// Test that a nvme_self_test routine for short time with no parameters will
// fail.
TEST_F(GrpcServiceTest, RunNvmeSelfTestShortRoutineNoParameters) {
std::unique_ptr<grpc_api::RunRoutineResponse> response;
auto request = std::make_unique<grpc_api::RunRoutineRequest>();
request->set_routine(grpc_api::ROUTINE_NVME_SHORT_SELF_TEST);
ExecuteRunRoutine(std::move(request), &response,
false /* is_valid_request */);
EXPECT_EQ(response->uuid(), 0);
EXPECT_EQ(response->status(), grpc_api::ROUTINE_STATUS_INVALID_FIELD);
}
// Test that a linear read routine with no parameters will fail.
TEST_F(GrpcServiceTest, RunDiskLinearReadRoutineNoParameters) {
std::unique_ptr<grpc_api::RunRoutineResponse> response;
auto request = std::make_unique<grpc_api::RunRoutineRequest>();
request->set_routine(grpc_api::ROUTINE_DISK_LINEAR_READ);
ExecuteRunRoutine(std::move(request), &response,
false /* is_valid_request */);
EXPECT_EQ(response->uuid(), 0);
EXPECT_EQ(response->status(), grpc_api::ROUTINE_STATUS_INVALID_FIELD);
}
// Test that we can request that the nvme_self_test routine for extended time
// be run.
TEST_F(GrpcServiceTest, RunNvmeSelfTestLongRoutine) {
std::unique_ptr<grpc_api::RunRoutineResponse> response;
ExecuteRunRoutine(MakeRunNvmeLongSelfTestRoutineRequest(), &response,
true /* is_valid_request */);
auto expected_response = MakeRunRoutineResponse();
EXPECT_THAT(*response, ProtobufEquals(*expected_response))
<< "Actual response: {" << response->ShortDebugString() << "}";
}
// Test that random read routine can be run.
TEST_F(GrpcServiceTest, RunDiskRandomReadRoutine) {
std::unique_ptr<grpc_api::RunRoutineResponse> response;
auto request = std::make_unique<grpc_api::RunRoutineRequest>();
request->set_routine(grpc_api::ROUTINE_DISK_RANDOM_READ);
request->mutable_disk_random_read_params()->set_length_seconds(10);
request->mutable_disk_random_read_params()->set_file_size_mb(1024);
ExecuteRunRoutine(std::move(request), &response, true /* is_valid_request */);
auto expected_response = MakeRunRoutineResponse();
EXPECT_THAT(*response, ProtobufEquals(*expected_response))
<< "Actual response: {" << response->ShortDebugString() << "}";
}
// Test that a nvme_self_test routine for extended time with no parameters will
// fail.
TEST_F(GrpcServiceTest, RunNvmeSelfTestLongRoutineNoParameters) {
std::unique_ptr<grpc_api::RunRoutineResponse> response;
auto request = std::make_unique<grpc_api::RunRoutineRequest>();
request->set_routine(grpc_api::ROUTINE_NVME_LONG_SELF_TEST);
ExecuteRunRoutine(std::move(request), &response,
false /* is_valid_request */);
EXPECT_EQ(response->uuid(), 0);
EXPECT_EQ(response->status(), grpc_api::ROUTINE_STATUS_INVALID_FIELD);
}
// Test that a random read routine with no parameters will fail.
TEST_F(GrpcServiceTest, RunDiskRandomReadRoutineNoParameters) {
std::unique_ptr<grpc_api::RunRoutineResponse> response;
auto request = std::make_unique<grpc_api::RunRoutineRequest>();
request->set_routine(grpc_api::ROUTINE_DISK_RANDOM_READ);
ExecuteRunRoutine(std::move(request), &response,
false /* is_valid_request */);
EXPECT_EQ(response->uuid(), 0);
EXPECT_EQ(response->status(), grpc_api::ROUTINE_STATUS_INVALID_FIELD);
}
// Test that a prime search routine with no parameters will fail.
TEST_F(GrpcServiceTest, RunPrimeSearchRoutineNoParameters) {
std::unique_ptr<grpc_api::RunRoutineResponse> response;
auto request = std::make_unique<grpc_api::RunRoutineRequest>();
request->set_routine(grpc_api::ROUTINE_PRIME_SEARCH);
ExecuteRunRoutine(std::move(request), &response,
false /* is_valid_request */);
EXPECT_EQ(response->uuid(), 0);
EXPECT_EQ(response->status(), grpc_api::ROUTINE_STATUS_INVALID_FIELD);
}
// Test that an empty string is a valid result.
TEST_F(GrpcServiceTest, GetConfigurationDataEmpty) {
std::unique_ptr<grpc_api::GetConfigurationDataResponse> response;
ExecuteGetConfigurationData("", &response);
EXPECT_EQ(response->json_configuration_data(), "");
}
TEST_F(GrpcServiceTest, GetConfigurationData) {
// The JSON configuration data is passed through from the cloud to DTC binary
// and might not be in JSON format.
constexpr char kFakeJsonConfigurationData[] = "Fake JSON Configuration Data";
std::unique_ptr<grpc_api::GetConfigurationDataResponse> response;
ExecuteGetConfigurationData(kFakeJsonConfigurationData, &response);
EXPECT_EQ(response->json_configuration_data(), kFakeJsonConfigurationData);
}
TEST_F(GrpcServiceTest, GetVpdFieldUnset) {
grpc_api::GetVpdFieldResponse::Status status;
std::string vpd_field_value;
ASSERT_NO_FATAL_FAILURE(ExecuteGetVpdField(
grpc_api::GetVpdFieldRequest::FIELD_UNSET, &status, &vpd_field_value));
EXPECT_EQ(status,
grpc_api::GetVpdFieldResponse::STATUS_ERROR_VPD_FIELD_UNKNOWN);
EXPECT_TRUE(vpd_field_value.empty());
}
TEST_F(GrpcServiceTest, GetDriveSystemDataTypeUnknown) {
auto request = std::make_unique<grpc_api::GetDriveSystemDataRequest>();
std::unique_ptr<grpc_api::GetDriveSystemDataResponse> response;
service()->GetDriveSystemData(std::move(request),
GrpcCallbackResponseSaver(&response));
auto expected_response =
std::make_unique<grpc_api::GetDriveSystemDataResponse>();
expected_response->set_status(
grpc_api::GetDriveSystemDataResponse::STATUS_ERROR_REQUEST_TYPE_UNKNOWN);
EXPECT_THAT(*response, ProtobufEquals(*expected_response))
<< "Actual response: {" << response->ShortDebugString() << "}";
}
TEST_F(GrpcServiceTest, GetDriveSystemDataInternalError) {
auto request = std::make_unique<grpc_api::GetDriveSystemDataRequest>();
request->set_type(grpc_api::GetDriveSystemDataRequest::SMART_ATTRIBUTES);
EXPECT_CALL(*delegate(), GetDriveSystemData(_, _))
.WillOnce(WithArgs<1>(
Invoke([](const base::Callback<void(const std::string& payload,
bool success)>& callback) {
callback.Run("", false /* success */);
})));
std::unique_ptr<grpc_api::GetDriveSystemDataResponse> response;
service()->GetDriveSystemData(std::move(request),
GrpcCallbackResponseSaver(&response));
auto expected_response =
std::make_unique<grpc_api::GetDriveSystemDataResponse>();
expected_response->set_status(
grpc_api::GetDriveSystemDataResponse::STATUS_ERROR_REQUEST_PROCESSING);
EXPECT_THAT(*response, ProtobufEquals(*expected_response))
<< "Actual response: {" << response->ShortDebugString() << "}";
}
TEST_F(GrpcServiceTest, RequestBluetoothDataNotification) {
auto request =
std::make_unique<grpc_api::RequestBluetoothDataNotificationRequest>();
EXPECT_CALL(*delegate(), RequestBluetoothDataNotification());
base::RunLoop run_loop;
service()->RequestBluetoothDataNotification(
std::move(request),
base::Bind(
[](base::Closure callback, grpc::Status status,
std::unique_ptr<
grpc_api::RequestBluetoothDataNotificationResponse>) {
callback.Run();
},
run_loop.QuitClosure()));
run_loop.Run();
}
class GetStatefulPartitionAvailableCapacityTest
: public GrpcServiceTest,
public testing::WithParamInterface<std::tuple<
base::Callback<chromeos::cros_healthd::mojom::TelemetryInfoPtr()>,
grpc_api::GetStatefulPartitionAvailableCapacityResponse::Status,
int32_t>> {
protected:
// Accessors to individual test parameters from the test parameter tuple
// returned by gtest's GetParam():
chromeos::cros_healthd::mojom::TelemetryInfoPtr get_probe_response() const {
return std::get<0>(GetParam()).Run();
}
grpc_api::GetStatefulPartitionAvailableCapacityResponse::Status
get_expected_status() const {
return std::get<1>(GetParam());
}
int32_t get_expected_capacity() const { return std::get<2>(GetParam()); }
};
TEST_P(GetStatefulPartitionAvailableCapacityTest, All) {
const std::vector<chromeos::cros_healthd::mojom::ProbeCategoryEnum>
kExpectedCategories{
chromeos::cros_healthd::mojom::ProbeCategoryEnum::kStatefulPartition};
chromeos::cros_healthd::mojom::TelemetryInfoPtr probe_response =
get_probe_response();
EXPECT_CALL(*delegate(), ProbeTelemetryInfo(kExpectedCategories, _))
.WillOnce(WithArgs<1>(Invoke(
[&probe_response](
MockGrpcServiceDelegate::ProbeTelemetryInfoCallback callback) {
std::move(callback).Run(std::move(probe_response));
})));
auto callback_impl =
[](grpc_api::GetStatefulPartitionAvailableCapacityResponse::Status status,
int32_t expected_capacity, base::Closure loop_callback,
grpc::Status grpcStatus,
std::unique_ptr<
grpc_api::GetStatefulPartitionAvailableCapacityResponse> reply) {
EXPECT_EQ(reply->status(), status);
EXPECT_EQ(reply->available_capacity_mb(), expected_capacity);
loop_callback.Run();
};
base::RunLoop run_loop;
auto callback = base::Bind(callback_impl, get_expected_status(),
get_expected_capacity(), run_loop.QuitClosure());
service()->GetStatefulPartitionAvailableCapacity(
std::make_unique<
grpc_api::GetStatefulPartitionAvailableCapacityRequest>(),
callback);
run_loop.Run();
}
INSTANTIATE_TEST_SUITE_P(
,
GetStatefulPartitionAvailableCapacityTest,
testing::Values(
std::make_tuple(
base::Bind([]() {
return chromeos::cros_healthd::mojom::TelemetryInfoPtr(nullptr);
}),
grpc_api::GetStatefulPartitionAvailableCapacityResponse::
STATUS_ERROR_REQUEST_PROCESSING,
0),
std::make_tuple(
base::Bind([]() {
return chromeos::cros_healthd::mojom::TelemetryInfo::New();
}),
grpc_api::GetStatefulPartitionAvailableCapacityResponse::
STATUS_ERROR_REQUEST_PROCESSING,
0),
std::make_tuple(
base::Bind([]() {
auto probe_response =
chromeos::cros_healthd::mojom::TelemetryInfo::New();
probe_response->stateful_partition_result =
chromeos::cros_healthd::mojom::StatefulPartitionResult::
NewError(chromeos::cros_healthd::mojom::ProbeError::New(
chromeos::cros_healthd::mojom::ErrorType::
kSystemUtilityError,
""));
return probe_response;
}),
grpc_api::GetStatefulPartitionAvailableCapacityResponse::
STATUS_ERROR_REQUEST_PROCESSING,
0),
std::make_tuple(
base::Bind([]() {
constexpr uint64_t kAvailableBytes = 220403699712ull;
auto probe_response =
chromeos::cros_healthd::mojom::TelemetryInfo::New();
probe_response
->stateful_partition_result = chromeos::cros_healthd::mojom::
StatefulPartitionResult::NewPartitionInfo(
chromeos::cros_healthd::mojom::StatefulPartitionInfo::New(
kAvailableBytes, 0));
return probe_response;
}),
grpc_api::GetStatefulPartitionAvailableCapacityResponse::STATUS_OK,
210100)));
class GrpcServiceWithMockSystemInfoServiceTest : public GrpcServiceTest {
public:
GrpcServiceWithMockSystemInfoServiceTest() = default;
~GrpcServiceWithMockSystemInfoServiceTest() override = default;
GrpcServiceWithMockSystemInfoServiceTest(
const GrpcServiceWithMockSystemInfoServiceTest&) = delete;
GrpcServiceWithMockSystemInfoServiceTest& operator=(
const GrpcServiceWithMockSystemInfoServiceTest&) = delete;
void SetUp() override {
GrpcServiceTest::SetUp();
auto mock = std::make_unique<StrictMock<MockSystemInfoService>>();
system_info_service_mock_ = mock.get();
service()->set_system_info_service_for_testing(std::move(mock));
}
void ExecuteGetOsVersion(
std::unique_ptr<grpc_api::GetOsVersionResponse>* response) {
auto request = std::make_unique<grpc_api::GetOsVersionRequest>();
service()->GetOsVersion(std::move(request),
GrpcCallbackResponseSaver(response));
}
protected:
// Owned by |service_| from GrpcServiceTest
MockSystemInfoService* system_info_service_mock_ = nullptr;
};
TEST_F(GrpcServiceWithMockSystemInfoServiceTest, GetOsVersionUnset) {
EXPECT_CALL(*system_info_service_mock_, GetOsVersion(NotNull()));
EXPECT_CALL(*system_info_service_mock_, GetOsMilestone(NotNull()));
std::unique_ptr<grpc_api::GetOsVersionResponse> response;
ExecuteGetOsVersion(&response);
ASSERT_TRUE(response);
EXPECT_TRUE(response->version().empty());
EXPECT_EQ(response->milestone(), 0);
}
TEST_F(GrpcServiceWithMockSystemInfoServiceTest, GetOsVersion) {
constexpr char kOsVersion[] = "11932.0.2019_03_20_1100";
constexpr int kMilestone = 75;
EXPECT_CALL(*system_info_service_mock_, GetOsVersion(NotNull()))
.WillOnce(DoAll(WithArgs<0>(SetArgPointee<0>(kOsVersion)), Return(true)));
EXPECT_CALL(*system_info_service_mock_, GetOsMilestone(NotNull()))
.WillOnce(DoAll(WithArgs<0>(SetArgPointee<0>(kMilestone)), Return(true)));
std::unique_ptr<grpc_api::GetOsVersionResponse> response;
ExecuteGetOsVersion(&response);
ASSERT_TRUE(response);
EXPECT_EQ(response->version(), kOsVersion);
EXPECT_EQ(response->milestone(), kMilestone);
}
class GrpcServiceWithMockSystemFilesServiceTest : public GrpcServiceTest {
public:
void SetUp() override {
GrpcServiceTest::SetUp();
auto fake = std::make_unique<StrictMock<MockSystemFilesService>>();
system_files_service_ = fake.get();
service()->set_system_files_service_for_testing(std::move(fake));
}
protected:
// Owned by |service_| from GrpcServiceTest
MockSystemFilesService* system_files_service_ = nullptr;
};
TEST_F(GrpcServiceWithMockSystemFilesServiceTest,
DirectoryAcpiButtonSingleFile) {
SystemFilesService::FileDumps directory_dump;
auto single_dump = std::make_unique<SystemFilesService::FileDump>();
single_dump->contents = FakeFileContents();
single_dump->path = base::FilePath(kTestFilePath);
single_dump->canonical_path = base::FilePath(kTestCanonicalFilePath);
directory_dump.push_back(std::move(single_dump));
EXPECT_CALL(*system_files_service_,
GetDirectoryDump(SystemFilesService::Directory::kProcAcpiButton))
.WillOnce(Return(
ByMove(MockSystemFilesService::CopyFileDumps(directory_dump))));
std::vector<grpc_api::FileDump> file_dumps;
ExecuteGetProcData(grpc_api::GetProcDataRequest::DIRECTORY_ACPI_BUTTON,
&file_dumps);
EXPECT_THAT(file_dumps,
GrpcDumpsEquivalentWithInternal(ByRef(directory_dump)));
}
TEST_F(GrpcServiceWithMockSystemFilesServiceTest,
DirectoryAcpiButtonMultiFile) {
SystemFilesService::FileDumps directory_dump;
auto first_dump = std::make_unique<SystemFilesService::FileDump>();
first_dump->contents = FakeFileContents();
first_dump->path = base::FilePath(kTestFilePath);
first_dump->canonical_path = base::FilePath(kTestCanonicalFilePath);
directory_dump.push_back(std::move(first_dump));
auto second_dump = std::make_unique<SystemFilesService::FileDump>();
second_dump->contents = FakeFileContents() + "file_2";
second_dump->path = base::FilePath(kTestFilePath).Append("2");
second_dump->canonical_path =
base::FilePath(kTestCanonicalFilePath).Append("3");
directory_dump.push_back(std::move(second_dump));
EXPECT_CALL(*system_files_service_,
GetDirectoryDump(SystemFilesService::Directory::kProcAcpiButton))
.WillOnce(Return(
ByMove(MockSystemFilesService::CopyFileDumps(directory_dump))));
std::vector<grpc_api::FileDump> file_dumps;
ExecuteGetProcData(grpc_api::GetProcDataRequest::DIRECTORY_ACPI_BUTTON,
&file_dumps);
EXPECT_THAT(file_dumps,
GrpcDumpsEquivalentWithInternal(ByRef(directory_dump)));
}
TEST_F(GrpcServiceWithMockSystemFilesServiceTest, DirectoryAcpiButtonEmpty) {
EXPECT_CALL(*system_files_service_,
GetDirectoryDump(SystemFilesService::Directory::kProcAcpiButton))
.WillOnce(Return(ByMove(SystemFilesService::FileDumps())));
std::vector<grpc_api::FileDump> file_dumps;
ExecuteGetProcData(grpc_api::GetProcDataRequest::DIRECTORY_ACPI_BUTTON,
&file_dumps);
EXPECT_EQ(file_dumps.size(), 0);
}
TEST_F(GrpcServiceWithMockSystemFilesServiceTest, DirectoryAcpiButtonMissing) {
EXPECT_CALL(*system_files_service_,
GetDirectoryDump(SystemFilesService::Directory::kProcAcpiButton))
.WillOnce(Return(ByMove(base::nullopt)));
std::vector<grpc_api::FileDump> file_dumps;
ExecuteGetProcData(grpc_api::GetProcDataRequest::DIRECTORY_ACPI_BUTTON,
&file_dumps);
EXPECT_EQ(file_dumps.size(), 0);
}
// Tests for the GetProcData() method of GrpcServiceTest when a
// single file is requested.
//
// This is a parameterized test with the following parameters:
// * |proc_data_request_type| - type of the GetProcData() request to be executed
// (see GetProcDataRequest::Type);
// * |expected_location| - SystemFilesService::File that should be requested
class SingleProcFileGrpcServiceTest
: public GrpcServiceWithMockSystemFilesServiceTest,
public testing::WithParamInterface<
std::tuple<grpc_api::GetProcDataRequest::Type,
SystemFilesService::File>> {
protected:
// Accessors to individual test parameters from the test parameter tuple
// returned by gtest's GetParam():
grpc_api::GetProcDataRequest::Type proc_data_request_type() const {
return std::get<0>(GetParam());
}
SystemFilesService::File expected_location() const {
return std::get<1>(GetParam());
}
};
// Test that GetProcData() returns a single item with the requested file data
// when the file exists.
TEST_P(SingleProcFileGrpcServiceTest, Success) {
SystemFilesService::FileDump file_dump;
file_dump.contents = FakeFileContents();
file_dump.path = base::FilePath(kTestFilePath);
file_dump.canonical_path = base::FilePath(kTestCanonicalFilePath);
EXPECT_CALL(*system_files_service_, GetFileDump(expected_location()))
.WillOnce(
Return(ByMove(MockSystemFilesService::CopyFileDump(file_dump))));
std::vector<grpc_api::FileDump> file_dumps;
ExecuteGetProcData(proc_data_request_type(), &file_dumps);
ASSERT_EQ(file_dumps.size(), 1);
EXPECT_EQ(file_dumps[0].contents(), file_dump.contents);
EXPECT_EQ(file_dumps[0].path(), file_dump.path.value());
EXPECT_EQ(file_dumps[0].canonical_path(), file_dump.canonical_path.value());
}
// Test that GetProcData() returns empty result when the file doesn't exist.
TEST_P(SingleProcFileGrpcServiceTest, NonExisting) {
EXPECT_CALL(*system_files_service_, GetFileDump(expected_location()))
.WillOnce(Return(ByMove(base::nullopt)));
std::vector<grpc_api::FileDump> file_dumps;
ExecuteGetProcData(proc_data_request_type(), &file_dumps);
EXPECT_EQ(file_dumps.size(), 0);
}
INSTANTIATE_TEST_SUITE_P(
,
SingleProcFileGrpcServiceTest,
testing::Values(
std::make_tuple(grpc_api::GetProcDataRequest::FILE_UPTIME,
SystemFilesService::File::kProcUptime),
std::make_tuple(grpc_api::GetProcDataRequest::FILE_MEMINFO,
SystemFilesService::File::kProcMeminfo),
std::make_tuple(grpc_api::GetProcDataRequest::FILE_LOADAVG,
SystemFilesService::File::kProcLoadavg),
std::make_tuple(grpc_api::GetProcDataRequest::FILE_STAT,
SystemFilesService::File::kProcStat),
std::make_tuple(grpc_api::GetProcDataRequest::FILE_NET_NETSTAT,
SystemFilesService::File::kProcNetNetstat),
std::make_tuple(grpc_api::GetProcDataRequest::FILE_NET_DEV,
SystemFilesService::File::kProcNetDev),
std::make_tuple(grpc_api::GetProcDataRequest::FILE_DISKSTATS,
SystemFilesService::File::kProcDiskstats),
std::make_tuple(grpc_api::GetProcDataRequest::FILE_CPUINFO,
SystemFilesService::File::kProcCpuinfo),
std::make_tuple(grpc_api::GetProcDataRequest::FILE_VMSTAT,
SystemFilesService::File::kProcVmstat)));
// Tests for the GetSysfsData() method of GrpcServiceTest when a
// directory is requested.
//
// This is a parameterized test with the following parameters:
// * |sysfs_data_request_type| - type of the GetSysfsData() request to be
// executed (see GetSysfsDataRequest::Type);
// * |expected_location| - SystemFilesService::Directory that should be
// requested
class SysfsDirectoryGrpcServiceTest
: public GrpcServiceWithMockSystemFilesServiceTest,
public testing::WithParamInterface<
std::tuple<grpc_api::GetSysfsDataRequest::Type,
SystemFilesService::Directory>> {
protected:
// Accessors to individual test parameters constructed from the test parameter
// tuple returned by gtest's GetParam():
grpc_api::GetSysfsDataRequest::Type sysfs_data_request_type() const {
return std::get<0>(GetParam());
}
SystemFilesService::Directory expected_location() const {
return std::get<1>(GetParam());
}
};
// Test that GetSysfsData() returns a single file when called on a directory
// containing a single file.
TEST_P(SysfsDirectoryGrpcServiceTest, SingleFile) {
SystemFilesService::FileDumps directory_dump;
auto single_dump = std::make_unique<SystemFilesService::FileDump>();
single_dump->contents = FakeFileContents();
single_dump->path = base::FilePath(kTestFilePath);
single_dump->canonical_path = base::FilePath(kTestCanonicalFilePath);
directory_dump.push_back(std::move(single_dump));
EXPECT_CALL(*system_files_service_, GetDirectoryDump(expected_location()))
.WillOnce(Return(
ByMove(MockSystemFilesService::CopyFileDumps(directory_dump))));
std::vector<grpc_api::FileDump> file_dumps;
ExecuteGetSysfsData(sysfs_data_request_type(), &file_dumps);
EXPECT_THAT(file_dumps,
GrpcDumpsEquivalentWithInternal(ByRef(directory_dump)));
}
// Test that GetSysfsData() returns a multiple files when called on a directory
// containing multiple files.
TEST_P(SysfsDirectoryGrpcServiceTest, MultiFile) {
SystemFilesService::FileDumps directory_dump;
auto first_dump = std::make_unique<SystemFilesService::FileDump>();
first_dump->contents = FakeFileContents();
first_dump->path = base::FilePath(kTestFilePath);
first_dump->canonical_path = base::FilePath(kTestCanonicalFilePath);
directory_dump.push_back(std::move(first_dump));
auto second_dump = std::make_unique<SystemFilesService::FileDump>();
second_dump->contents = FakeFileContents() + "file_2";
second_dump->path = base::FilePath(kTestFilePath).Append("2");
second_dump->canonical_path =
base::FilePath(kTestCanonicalFilePath).Append("3");
directory_dump.push_back(std::move(second_dump));
EXPECT_CALL(*system_files_service_, GetDirectoryDump(expected_location()))
.WillOnce(Return(
ByMove(MockSystemFilesService::CopyFileDumps(directory_dump))));
std::vector<grpc_api::FileDump> file_dumps;
ExecuteGetSysfsData(sysfs_data_request_type(), &file_dumps);
EXPECT_THAT(file_dumps,
GrpcDumpsEquivalentWithInternal(ByRef(directory_dump)));
}
// Test that GetSysfsData() returns an empty result when the directory doesn't
// exist.
TEST_P(SysfsDirectoryGrpcServiceTest, NonExisting) {
EXPECT_CALL(*system_files_service_, GetDirectoryDump(expected_location()))
.WillOnce(Return(ByMove(base::nullopt)));
std::vector<grpc_api::FileDump> file_dumps;
ExecuteGetSysfsData(sysfs_data_request_type(), &file_dumps);
EXPECT_EQ(file_dumps.size(), 0);
}
// Test that GetSysfsData() returns an empty result when the directory is
// empty.
TEST_P(SysfsDirectoryGrpcServiceTest, Empty) {
EXPECT_CALL(*system_files_service_, GetDirectoryDump(expected_location()))
.WillOnce(Return(ByMove(SystemFilesService::FileDumps())));
std::vector<grpc_api::FileDump> file_dumps;
ExecuteGetSysfsData(sysfs_data_request_type(), &file_dumps);
EXPECT_EQ(file_dumps.size(), 0);
}
INSTANTIATE_TEST_SUITE_P(
,
SysfsDirectoryGrpcServiceTest,
testing::Values(
std::make_tuple(grpc_api::GetSysfsDataRequest::CLASS_HWMON,
SystemFilesService::Directory::kSysClassHwmon),
std::make_tuple(grpc_api::GetSysfsDataRequest::CLASS_THERMAL,
SystemFilesService::Directory::kSysClassThermal),
std::make_tuple(grpc_api::GetSysfsDataRequest::FIRMWARE_DMI_TABLES,
SystemFilesService::Directory::kSysFirmwareDmiTables),
std::make_tuple(grpc_api::GetSysfsDataRequest::CLASS_POWER_SUPPLY,
SystemFilesService::Directory::kSysClassPowerSupply),
std::make_tuple(grpc_api::GetSysfsDataRequest::CLASS_BACKLIGHT,
SystemFilesService::Directory::kSysClassBacklight),
std::make_tuple(grpc_api::GetSysfsDataRequest::CLASS_NETWORK,
SystemFilesService::Directory::kSysClassNetwork),
std::make_tuple(grpc_api::GetSysfsDataRequest::DEVICES_SYSTEM_CPU,
SystemFilesService::Directory::kSysDevicesSystemCpu)));
// Tests for the GetEcTelemetry() method of GrpcServiceTest.
//
// This is a parameterized test with the following parameters:
// * |request_payload| - payload of the GetEcTelemetry() request;
// * |expected_response_status| - expected GetEcTelemetry() response status;
// * |expected_response_payload| - expected GetEcTelemetry() response payload.
class GetEcTelemetryGrpcServiceTest
: public GrpcServiceTest,
public testing::WithParamInterface<
std::tuple<std::string /* request_payload */,
grpc_api::GetEcTelemetryResponse::
Status /* expected_response_status */,
std::string /* expected_response_payload */>> {
protected:
std::string request_payload() const { return std::get<0>(GetParam()); }
grpc_api::GetEcTelemetryResponse::Status expected_response_status() const {
return std::get<1>(GetParam());
}
std::string expected_response_payload() const {
return std::get<2>(GetParam());
}
base::FilePath devfs_telemetry_file() const {
return temp_dir_path().Append(kEcGetTelemetryFilePath);
}
};
// Test that GetEcTelemetry() response contains expected |status| and |payload|
// field values.
TEST_P(GetEcTelemetryGrpcServiceTest, Base) {
// Write request and response payload because EC telemetry char device is
// non-seekable.
EXPECT_TRUE(WriteFileAndCreateParentDirs(
devfs_telemetry_file(), request_payload() + expected_response_payload()));
std::unique_ptr<grpc_api::GetEcTelemetryResponse> response;
ExecuteGetEcTelemetry(request_payload(), &response);
ASSERT_TRUE(response);
auto expected_response = MakeGetEcTelemetryResponse(
expected_response_status(), expected_response_payload());
EXPECT_THAT(*response, ProtobufEquals(*expected_response))
<< "Actual response: {" << response->ShortDebugString() << "}";
}
INSTANTIATE_TEST_SUITE_P(
,
GetEcTelemetryGrpcServiceTest,
testing::Values(
std::make_tuple(FakeFileContents(),
grpc_api::GetEcTelemetryResponse::STATUS_OK,
FakeFileContents()),
std::make_tuple(std::string("A", kEcGetTelemetryPayloadMaxSize),
grpc_api::GetEcTelemetryResponse::STATUS_OK,
std::string("B", kEcGetTelemetryPayloadMaxSize)),
std::make_tuple(
"",
grpc_api::GetEcTelemetryResponse::STATUS_ERROR_INPUT_PAYLOAD_EMPTY,
""),
std::make_tuple(std::string("A", kEcGetTelemetryPayloadMaxSize + 1),
grpc_api::GetEcTelemetryResponse::
STATUS_ERROR_INPUT_PAYLOAD_MAX_SIZE_EXCEEDED,
"")));
// Tests for the PerformWebRequest() method of GrpcService.
//
// This is a parameterized test with the following parameters:
//
// The input arguments to create a PerformWebRequestParameter:
// * |http_method| - gRPC PerformWebRequest HTTP method.
// * |url| - gRPC PerformWebRequest URL.
// * |headers| - gRPC PerformWebRequest headers list.
// * |request_body| - gRPC PerformWebRequest request body.
//
// The intermediate parameters to verify by the test:
// * |delegate_http_method| - this is an optional value, a nullptr if the
// intermediate verification is not needed.
// GrpcService's Delegate's HTTP
// method to verify the mapping between gRPC and
// Delegate's HTTP method names.
//
// The expected response values to verify PerformWebRequestResponse:
// * |status| - gRPC PerformWebRequestResponse status.
// * |http_status| - this is an optional value. gRPC PerformWebRequestResponse
// HTTP status. If there is no HTTP status needed for
// the passed |status|, pass a nullptr.
// * |response_body| - this is an optional value. gRPC PerformWebRequestResponse
// body. If not set, pass a nullptr.
class PerformWebRequestGrpcServiceTest
: public GrpcServiceTest,
public testing::WithParamInterface<
std::tuple<grpc_api::PerformWebRequestParameter::HttpMethod,
std::string /* URL */,
std::vector<std::string> /* headers */,
std::string /* request body */,
const DelegateWebRequestHttpMethod*,
grpc_api::PerformWebRequestResponse::Status /* status */,
const int* /* HTTP status */,
const char* /* response body */>> {
protected:
grpc_api::PerformWebRequestParameter::HttpMethod http_method() {
return std::get<0>(GetParam());
}
std::string url() const { return std::get<1>(GetParam()); }
std::vector<std::string> headers() const { return std::get<2>(GetParam()); }
std::string request_body() const { return std::get<3>(GetParam()); }
const DelegateWebRequestHttpMethod* delegate_http_method() const {
return std::get<4>(GetParam());
}
grpc_api::PerformWebRequestResponse::Status status() const {
return std::get<5>(GetParam());
}
const int* http_status() const { return std::get<6>(GetParam()); }
const char* response_body() const { return std::get<7>(GetParam()); }
};
// Tests that PerformWebRequest() returns an appropriate status and HTTP status
// code.
TEST_P(PerformWebRequestGrpcServiceTest, PerformWebRequest) {
std::unique_ptr<grpc_api::PerformWebRequestResponse> response;
ExecutePerformWebRequest(http_method(), url(), headers(), request_body(),
delegate_http_method(), &response);
ASSERT_TRUE(response);
auto expected_response =
MakePerformWebRequestResponse(status(), http_status(), response_body());
EXPECT_THAT(*response, ProtobufEquals(*expected_response))
<< "Actual response: {" << response->ShortDebugString() << "}";
}
// Test cases to run a PerformWebRequest test.
// Make sure that the delegate_http_header is not set if the flow does not
// involve the calls to GrpcService::Delegate.
INSTANTIATE_TEST_SUITE_P(
,
PerformWebRequestGrpcServiceTest,
testing::Values(
// Tests an incorrect HTTP method.
std::make_tuple(grpc_api::PerformWebRequestParameter::HTTP_METHOD_UNSET,
kCorrectUrl,
std::vector<std::string>() /* headers */,
"" /* request_body */,
nullptr /* delegate_http_method */,
grpc_api::PerformWebRequestResponse ::
STATUS_ERROR_REQUIRED_FIELD_MISSING,
nullptr /* http_status */,
nullptr /* response_body */),
// Tests an empty URL.
std::make_tuple(
grpc_api::PerformWebRequestParameter::HTTP_METHOD_GET,
"" /* url */,
std::vector<std::string>() /* headers */,
"" /* request_body */,
nullptr /* delegate_http_method */,
grpc_api::PerformWebRequestResponse ::STATUS_ERROR_INVALID_URL,
nullptr /* http_status */,
nullptr /* response_body */),
// Tests a non-HTTPS URL.
std::make_tuple(
grpc_api::PerformWebRequestParameter::HTTP_METHOD_PUT,
kBadNonHttpsUrl,
std::vector<std::string>() /* headers */,
"" /* request_body */,
nullptr /* delegate_http_method */,
grpc_api::PerformWebRequestResponse::STATUS_ERROR_INVALID_URL,
nullptr /* http_status */,
nullptr /* response_body */),
// Tests the maximum allowed number of headers with HTTP method GET.
std::make_tuple(grpc_api::PerformWebRequestParameter::HTTP_METHOD_GET,
kCorrectUrl,
std::vector<std::string>(
kMaxNumberOfHeadersInPerformWebRequestParameter,
""),
"" /* request_body */,
&kDelegateWebRequestHttpMethodGet,
grpc_api::PerformWebRequestResponse::STATUS_OK,
&kHttpStatusOk,
kFakeWebResponseBody),
// The HTTP method is HEAD.
std::make_tuple(grpc_api::PerformWebRequestParameter::HTTP_METHOD_HEAD,
kCorrectUrl,
std::vector<std::string>(
kMaxNumberOfHeadersInPerformWebRequestParameter,
""),
"" /* request_body */,
&kDelegateWebRequestHttpMethodHead,
grpc_api::PerformWebRequestResponse::STATUS_OK,
&kHttpStatusOk,
kFakeWebResponseBody),
// The HTTP method is POST.
std::make_tuple(grpc_api::PerformWebRequestParameter::HTTP_METHOD_POST,
kCorrectUrl,
std::vector<std::string>() /* headers */,
"" /* request_body */,
&kDelegateWebRequestHttpMethodPost,
grpc_api::PerformWebRequestResponse::STATUS_OK,
&kHttpStatusOk,
kFakeWebResponseBody),
// The HTTP method is PATCH.
std::make_tuple(grpc_api::PerformWebRequestParameter::HTTP_METHOD_PATCH,
kCorrectUrl,
std::vector<std::string>() /* headers */,
"" /* request_body */,
&kDelegateWebRequestHttpMethodPatch,
grpc_api::PerformWebRequestResponse::STATUS_OK,
&kHttpStatusOk,
kFakeWebResponseBody),
// Tests the minimum not allowed number of headers.
std::make_tuple(
grpc_api::PerformWebRequestParameter::HTTP_METHOD_GET,
kCorrectUrl,
std::vector<std::string>(
kMaxNumberOfHeadersInPerformWebRequestParameter + 1, ""),
"" /* request_body */,
nullptr /* delegate_http_method */,
grpc_api::PerformWebRequestResponse::STATUS_ERROR_MAX_SIZE_EXCEEDED,
nullptr /* http_status */,
nullptr /* response_body */),
// Tests the total size of "string" and "byte" fields of
// PerformWebRequestParameter = 1Mb, the HTTP method is PUT.
std::make_tuple(grpc_api::PerformWebRequestParameter::HTTP_METHOD_PUT,
kCorrectUrl,
std::vector<std::string>() /* headers */,
std::string(kMaxPerformWebRequestParameterSizeInBytes -
strlen(kCorrectUrl),
'A'),
&kDelegateWebRequestHttpMethodPut,
grpc_api::PerformWebRequestResponse::STATUS_OK,
&kHttpStatusOk,
kFakeWebResponseBody),
// Tests the total size of "string" and "byte" fields of
// PerformWebRequestParameter > 1Mb.
std::make_tuple(
grpc_api::PerformWebRequestParameter::HTTP_METHOD_GET,
kCorrectUrl,
std::vector<std::string>() /* headers */,
std::string(kMaxPerformWebRequestParameterSizeInBytes, 'A'),
nullptr /* delegate_http_method */,
grpc_api::PerformWebRequestResponse::STATUS_ERROR_MAX_SIZE_EXCEEDED,
nullptr /* http_status */,
nullptr /* response_body */)));
// Tests for the GetRoutineUpdate() method of GrpcService.
//
// This is a parameterized test with the following parameters:
//
// The input arguments to create a GetRoutineUpdateRequest:
// * |command| - gRPC GetRoutineUpdateRequest command.
class GetRoutineUpdateRequestGrpcServiceTest
: public GrpcServiceTest,
public testing::WithParamInterface<
grpc_api::GetRoutineUpdateRequest::Command /* command */> {
protected:
grpc_api::GetRoutineUpdateRequest::Command command() const {
return GetParam();
}
};
// Tests that GetRoutineUpdate() returns an appropriate uuid, status, progress
// percent, user message and output.
TEST_P(GetRoutineUpdateRequestGrpcServiceTest,
GetRoutineUpdateRequestWithOutput) {
std::unique_ptr<grpc_api::GetRoutineUpdateResponse> response;
constexpr bool kIncludeOutput = true;
ExecuteGetRoutineUpdate(kFakeUuid, command(), kIncludeOutput, &response);
ASSERT_TRUE(response);
auto expected_response =
MakeGetRoutineUpdateResponse(kFakeUuid, kIncludeOutput);
EXPECT_THAT(*response, ProtobufEquals(*expected_response))
<< "Actual response: {" << response->ShortDebugString() << "}";
}
// Tests that GetRoutineUpdate() does not return output when include_output is
// false.
TEST_P(GetRoutineUpdateRequestGrpcServiceTest,
GetRoutineUpdateRequestNoOutput) {
std::unique_ptr<grpc_api::GetRoutineUpdateResponse> response;
constexpr bool kIncludeOutput = false;
ExecuteGetRoutineUpdate(kFakeUuid, command(), kIncludeOutput, &response);
ASSERT_TRUE(response);
auto expected_response =
MakeGetRoutineUpdateResponse(kFakeUuid, kIncludeOutput);
EXPECT_THAT(*response, ProtobufEquals(*expected_response))
<< "Actual response: {" << response->ShortDebugString() << "}";
}
// Test cases to run a GetRoutineUpdateRequest test.
INSTANTIATE_TEST_SUITE_P(,
GetRoutineUpdateRequestGrpcServiceTest,
testing::Values(
// Test each possible command value.
grpc_api::GetRoutineUpdateRequest::RESUME,
grpc_api::GetRoutineUpdateRequest::CANCEL,
grpc_api::GetRoutineUpdateRequest::GET_STATUS));
// Test for the GetVpdField() method of GrpcService.
//
// This is a parametrized test with the following parameters:
// * |vpd_field| - the requested VPD field.
// * |expected_vpd_field| - SystemFilesService::VpdField that should be
// requested.
class GetVpdFieldGrpcServiceTest
: public GrpcServiceWithMockSystemFilesServiceTest,
public testing::WithParamInterface<
std::tuple<grpc_api::GetVpdFieldRequest::VpdField /* vpd_field */,
SystemFilesService::VpdField /* expected_vpd_field */>> {
protected:
grpc_api::GetVpdFieldRequest::VpdField vpd_field() const {
return std::get<0>(GetParam());
}
SystemFilesService::VpdField expected_vpd_field() const {
return std::get<1>(GetParam());
}
};
// Test that GetVpdField() returns requested VPD field.
TEST_P(GetVpdFieldGrpcServiceTest, Success) {
constexpr char kFakeVpdField[] = "VPD test value";
EXPECT_CALL(*system_files_service_, GetVpdField(expected_vpd_field()))
.WillOnce(Return(kFakeVpdField));
grpc_api::GetVpdFieldResponse::Status status;
std::string vpd_field_value;
ASSERT_NO_FATAL_FAILURE(
ExecuteGetVpdField(vpd_field(), &status, &vpd_field_value));
EXPECT_EQ(status, grpc_api::GetVpdFieldResponse::STATUS_OK);
EXPECT_EQ(vpd_field_value, kFakeVpdField);
}
// Test that GetVpdField() returns error if VPD field does not exist.
TEST_P(GetVpdFieldGrpcServiceTest, NoVpdField) {
EXPECT_CALL(*system_files_service_, GetVpdField(expected_vpd_field()))
.WillOnce(Return(base::nullopt));
grpc_api::GetVpdFieldResponse::Status status;
std::string vpd_field_value;
ASSERT_NO_FATAL_FAILURE(
ExecuteGetVpdField(vpd_field(), &status, &vpd_field_value));
EXPECT_EQ(status, grpc_api::GetVpdFieldResponse::STATUS_ERROR_INTERNAL);
EXPECT_TRUE(vpd_field_value.empty());
}
INSTANTIATE_TEST_SUITE_P(
,
GetVpdFieldGrpcServiceTest,
testing::Values(
std::make_tuple(grpc_api::GetVpdFieldRequest::FIELD_SERIAL_NUMBER,
SystemFilesService::VpdField::kSerialNumber),
std::make_tuple(grpc_api::GetVpdFieldRequest::FIELD_MODEL_NAME,
SystemFilesService::VpdField::kModelName),
std::make_tuple(grpc_api::GetVpdFieldRequest::FIELD_ASSET_ID,
SystemFilesService::VpdField::kAssetId),
std::make_tuple(grpc_api::GetVpdFieldRequest::FIELD_SKU_NUMBER,
SystemFilesService::VpdField::kSkuNumber),
std::make_tuple(grpc_api::GetVpdFieldRequest::FIELD_UUID_ID,
SystemFilesService::VpdField::kUuid),
std::make_tuple(grpc_api::GetVpdFieldRequest::FIELD_MANUFACTURE_DATE,
SystemFilesService::VpdField::kMfgDate),
std::make_tuple(grpc_api::GetVpdFieldRequest::FIELD_ACTIVATE_DATE,
SystemFilesService::VpdField::kActivateDate),
std::make_tuple(grpc_api::GetVpdFieldRequest::FIELD_SYSTEM_ID,
SystemFilesService::VpdField::kSystemId)));
// Test for the GetDriveSystemData() method of GrpcService.
//
// This is a parametrized test with the following parameters:
// * |vpd_field| - the requested drive system data type
// * |expected_data_type| - the expected internal drive system data type value.
class GetDriveSystemDataGrpcServiceTest
: public GrpcServiceTest,
public testing::WithParamInterface<
std::tuple<grpc_api::GetDriveSystemDataRequest::Type /* data_type */,
DelegateDriveSystemDataType /* expected_data_type */>> {
protected:
grpc_api::GetDriveSystemDataRequest::Type data_type() const {
return std::get<0>(GetParam());
}
DelegateDriveSystemDataType expected_data_type() const {
return std::get<1>(GetParam());
}
};
// Test that GetDriveSystemData() parses gRPC message and calls delegate
// function with appropriate data type.
TEST_P(GetDriveSystemDataGrpcServiceTest, GetDriveSystem) {
constexpr char kFakeDriveSystemData[] = "Fake DriveSystem data";
auto request = std::make_unique<grpc_api::GetDriveSystemDataRequest>();
request->set_type(data_type());
EXPECT_CALL(*delegate(), GetDriveSystemData(expected_data_type(), _))
.WillOnce(WithArgs<1>(
Invoke([kFakeDriveSystemData](
const base::Callback<void(const std::string& payload,
bool success)>& callback) {
callback.Run(kFakeDriveSystemData, true /* success */);
})));
std::unique_ptr<grpc_api::GetDriveSystemDataResponse> response;
service()->GetDriveSystemData(std::move(request),
GrpcCallbackResponseSaver(&response));
auto expected_response =
std::make_unique<grpc_api::GetDriveSystemDataResponse>();
expected_response->set_status(
grpc_api::GetDriveSystemDataResponse::STATUS_OK);
expected_response->set_payload(kFakeDriveSystemData);
EXPECT_THAT(*response, ProtobufEquals(*expected_response))
<< "Actual response: {" << response->ShortDebugString() << "}";
}
INSTANTIATE_TEST_SUITE_P(
,
GetDriveSystemDataGrpcServiceTest,
testing::Values(
std::make_tuple(grpc_api::GetDriveSystemDataRequest::SMART_ATTRIBUTES,
DelegateDriveSystemDataType::kSmartAttributes),
std::make_tuple(
grpc_api::GetDriveSystemDataRequest::IDENTITY_ATTRIBUTES,
DelegateDriveSystemDataType::kIdentityAttributes)));
} // namespace
} // namespace diagnostics