| // 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/message_loop/message_loop.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/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::MessageLoop message_loop_; |
| 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 |