cros_healthd: add prime search routines
Add a routine to calculate prime number repeatedly and validate the calculation results are correct in a duration. Bug: b:146513388 Test: chromeos_unittests --gtest_filter=CrosHealthdServiceConnectionTest.* Change-Id: I29c3d71d2b0f9d86043e552e135bc9178c95014f Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2049986 Commit-Queue: Oleh Lamzin <lamzin@google.com> Reviewed-by: Oleh Lamzin <lamzin@google.com> Reviewed-by: Maksim Ivanov <emaxx@chromium.org> Reviewed-by: Paul Moy <pmoy@chromium.org> Reviewed-by: Steven Bennetts <stevenjb@chromium.org> Reviewed-by: Daniel Cheng <dcheng@chromium.org> Cr-Commit-Position: refs/heads/master@{#754004}
This commit is contained in:
chrome/browser/chromeos/policy/remote_commands
chromeos
dbus
services
@ -400,6 +400,31 @@ void DeviceCommandRunRoutineJob::RunImpl(CallbackWithResult succeeded_callback,
|
||||
std::move(failed_callback)));
|
||||
break;
|
||||
}
|
||||
case chromeos::cros_healthd::mojom::DiagnosticRoutineEnum::kPrimeSearch: {
|
||||
constexpr char kLengthSecondsFieldName[] = "lengthSeconds";
|
||||
constexpr char kMaxNumFieldName[] = "maxNum";
|
||||
base::Optional<int> length_seconds =
|
||||
params_dict_.FindIntKey(kLengthSecondsFieldName);
|
||||
base::Optional<int> max_num = params_dict_.FindIntKey(kMaxNumFieldName);
|
||||
if (!length_seconds.has_value() || length_seconds.value() < 0 ||
|
||||
!max_num.has_value() || max_num.value() < 0) {
|
||||
SYSLOG(ERROR) << "Invalid parameters for prime search routine.";
|
||||
base::ThreadTaskRunnerHandle::Get()->PostTask(
|
||||
FROM_HERE, base::BindOnce(std::move(failed_callback),
|
||||
std::make_unique<Payload>(
|
||||
MakeInvalidParametersResponse())));
|
||||
break;
|
||||
}
|
||||
auto exec_duration = base::TimeDelta::FromSeconds(length_seconds.value());
|
||||
chromeos::cros_healthd::ServiceConnection::GetInstance()
|
||||
->RunPrimeSearchRoutine(
|
||||
exec_duration, max_num.value(),
|
||||
base::BindOnce(
|
||||
&DeviceCommandRunRoutineJob::OnCrosHealthdResponseReceived,
|
||||
weak_ptr_factory_.GetWeakPtr(), std::move(succeeded_callback),
|
||||
std::move(failed_callback)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -67,6 +67,10 @@ constexpr char kNvmeSelfTestTypeFieldName[] = "nvmeSelfTestType";
|
||||
constexpr char kTypeFieldName[] = "type";
|
||||
constexpr char kFileSizeMbFieldName[] = "fileSizeMb";
|
||||
|
||||
// String constants identifying the parameter fields for the prime search
|
||||
// routine
|
||||
constexpr char kMaxNumFieldName[] = "maxNum";
|
||||
|
||||
// Dummy values to populate cros_healthd's RunRoutineResponse.
|
||||
constexpr uint32_t kId = 11;
|
||||
constexpr chromeos::cros_healthd::mojom::DiagnosticRoutineStatusEnum kStatus =
|
||||
@ -1400,4 +1404,149 @@ TEST_F(DeviceCommandRunRoutineJobTest, RunDiskReadRoutineInvalidFileSizeMb) {
|
||||
run_loop.Run();
|
||||
}
|
||||
|
||||
TEST_F(DeviceCommandRunRoutineJobTest, RunPrimeSearchRoutineSuccess) {
|
||||
// Test that the routine succeeds with all parameters specified.
|
||||
auto run_routine_response =
|
||||
chromeos::cros_healthd::mojom::RunRoutineResponse::New(kId, kStatus);
|
||||
chromeos::cros_healthd::FakeCrosHealthdClient::Get()
|
||||
->SetRunRoutineResponseForTesting(run_routine_response);
|
||||
base::Value params_dict(base::Value::Type::DICTIONARY);
|
||||
params_dict.SetIntKey(kLengthSecondsFieldName,
|
||||
/*length_seconds=*/2342);
|
||||
params_dict.SetIntKey(kMaxNumFieldName,
|
||||
/*max_num=*/100000);
|
||||
std::unique_ptr<RemoteCommandJob> job =
|
||||
std::make_unique<DeviceCommandRunRoutineJob>();
|
||||
InitializeJob(
|
||||
job.get(), kUniqueID, test_start_time_, base::TimeDelta::FromSeconds(30),
|
||||
/*terminate_upon_input=*/false,
|
||||
chromeos::cros_healthd::mojom::DiagnosticRoutineEnum::kPrimeSearch,
|
||||
std::move(params_dict));
|
||||
base::RunLoop run_loop;
|
||||
bool success =
|
||||
job->Run(base::Time::Now(), base::TimeTicks::Now(),
|
||||
base::BindLambdaForTesting([&]() {
|
||||
EXPECT_EQ(job->status(), RemoteCommandJob::SUCCEEDED);
|
||||
std::unique_ptr<std::string> payload = job->GetResultPayload();
|
||||
EXPECT_TRUE(payload);
|
||||
EXPECT_EQ(CreateSuccessPayload(kId, kStatus), *payload);
|
||||
run_loop.Quit();
|
||||
}));
|
||||
EXPECT_TRUE(success);
|
||||
run_loop.Run();
|
||||
}
|
||||
|
||||
TEST_F(DeviceCommandRunRoutineJobTest,
|
||||
RunPrimeSearchRoutineMissingLengthSeconds) {
|
||||
// Test that leaving out the length_seconds parameter causes the routine to
|
||||
// fail.
|
||||
base::Value params_dict(base::Value::Type::DICTIONARY);
|
||||
params_dict.SetIntKey(kMaxNumFieldName,
|
||||
/*max_num=*/100000);
|
||||
std::unique_ptr<RemoteCommandJob> job =
|
||||
std::make_unique<DeviceCommandRunRoutineJob>();
|
||||
InitializeJob(
|
||||
job.get(), kUniqueID, test_start_time_, base::TimeDelta::FromSeconds(30),
|
||||
/*terminate_upon_input=*/false,
|
||||
chromeos::cros_healthd::mojom::DiagnosticRoutineEnum::kPrimeSearch,
|
||||
std::move(params_dict));
|
||||
base::RunLoop run_loop;
|
||||
bool success =
|
||||
job->Run(base::Time::Now(), base::TimeTicks::Now(),
|
||||
base::BindLambdaForTesting([&]() {
|
||||
EXPECT_EQ(job->status(), RemoteCommandJob::FAILED);
|
||||
std::unique_ptr<std::string> payload = job->GetResultPayload();
|
||||
EXPECT_TRUE(payload);
|
||||
EXPECT_EQ(CreateInvalidParametersFailurePayload(), *payload);
|
||||
run_loop.Quit();
|
||||
}));
|
||||
EXPECT_TRUE(success);
|
||||
run_loop.Run();
|
||||
}
|
||||
|
||||
TEST_F(DeviceCommandRunRoutineJobTest, RunPrimeSearchRoutineMissingMaxNum) {
|
||||
// Test that leaving out the max_num parameter causes the routine to fail.
|
||||
base::Value params_dict(base::Value::Type::DICTIONARY);
|
||||
params_dict.SetIntKey(kLengthSecondsFieldName,
|
||||
/*length_seconds=*/2342);
|
||||
std::unique_ptr<RemoteCommandJob> job =
|
||||
std::make_unique<DeviceCommandRunRoutineJob>();
|
||||
InitializeJob(
|
||||
job.get(), kUniqueID, test_start_time_, base::TimeDelta::FromSeconds(30),
|
||||
/*terminate_upon_input=*/false,
|
||||
chromeos::cros_healthd::mojom::DiagnosticRoutineEnum::kPrimeSearch,
|
||||
std::move(params_dict));
|
||||
base::RunLoop run_loop;
|
||||
bool success =
|
||||
job->Run(base::Time::Now(), base::TimeTicks::Now(),
|
||||
base::BindLambdaForTesting([&]() {
|
||||
EXPECT_EQ(job->status(), RemoteCommandJob::FAILED);
|
||||
std::unique_ptr<std::string> payload = job->GetResultPayload();
|
||||
EXPECT_TRUE(payload);
|
||||
EXPECT_EQ(CreateInvalidParametersFailurePayload(), *payload);
|
||||
run_loop.Quit();
|
||||
}));
|
||||
EXPECT_TRUE(success);
|
||||
run_loop.Run();
|
||||
}
|
||||
|
||||
TEST_F(DeviceCommandRunRoutineJobTest,
|
||||
RunPrimeSearchRoutineInvalidLengthSeconds) {
|
||||
// Test that an invalid value for the length_seconds parameter causes the
|
||||
// routine to fail.
|
||||
base::Value params_dict(base::Value::Type::DICTIONARY);
|
||||
params_dict.SetIntKey(kLengthSecondsFieldName,
|
||||
/*length_seconds=*/-1);
|
||||
params_dict.SetIntKey(kMaxNumFieldName,
|
||||
/*max_num=*/100000);
|
||||
std::unique_ptr<RemoteCommandJob> job =
|
||||
std::make_unique<DeviceCommandRunRoutineJob>();
|
||||
InitializeJob(
|
||||
job.get(), kUniqueID, test_start_time_, base::TimeDelta::FromSeconds(30),
|
||||
/*terminate_upon_input=*/false,
|
||||
chromeos::cros_healthd::mojom::DiagnosticRoutineEnum::kPrimeSearch,
|
||||
std::move(params_dict));
|
||||
base::RunLoop run_loop;
|
||||
bool success =
|
||||
job->Run(base::Time::Now(), base::TimeTicks::Now(),
|
||||
base::BindLambdaForTesting([&]() {
|
||||
EXPECT_EQ(job->status(), RemoteCommandJob::FAILED);
|
||||
std::unique_ptr<std::string> payload = job->GetResultPayload();
|
||||
EXPECT_TRUE(payload);
|
||||
EXPECT_EQ(CreateInvalidParametersFailurePayload(), *payload);
|
||||
run_loop.Quit();
|
||||
}));
|
||||
EXPECT_TRUE(success);
|
||||
run_loop.Run();
|
||||
}
|
||||
|
||||
TEST_F(DeviceCommandRunRoutineJobTest, RunPrimeSearchRoutineInvalidMaxNum) {
|
||||
// Test that an invalid value for the max_num parameter causes the
|
||||
// routine to fail.
|
||||
base::Value params_dict(base::Value::Type::DICTIONARY);
|
||||
params_dict.SetIntKey(kLengthSecondsFieldName,
|
||||
/*length_seconds=*/2342);
|
||||
params_dict.SetIntKey(kMaxNumFieldName,
|
||||
/*max_num=*/-1);
|
||||
std::unique_ptr<RemoteCommandJob> job =
|
||||
std::make_unique<DeviceCommandRunRoutineJob>();
|
||||
InitializeJob(
|
||||
job.get(), kUniqueID, test_start_time_, base::TimeDelta::FromSeconds(30),
|
||||
/*terminate_upon_input=*/false,
|
||||
chromeos::cros_healthd::mojom::DiagnosticRoutineEnum::kPrimeSearch,
|
||||
std::move(params_dict));
|
||||
base::RunLoop run_loop;
|
||||
bool success =
|
||||
job->Run(base::Time::Now(), base::TimeTicks::Now(),
|
||||
base::BindLambdaForTesting([&]() {
|
||||
EXPECT_EQ(job->status(), RemoteCommandJob::FAILED);
|
||||
std::unique_ptr<std::string> payload = job->GetResultPayload();
|
||||
EXPECT_TRUE(payload);
|
||||
EXPECT_EQ(CreateInvalidParametersFailurePayload(), *payload);
|
||||
run_loop.Quit();
|
||||
}));
|
||||
EXPECT_TRUE(success);
|
||||
run_loop.Run();
|
||||
}
|
||||
|
||||
} // namespace policy
|
||||
|
@ -108,6 +108,13 @@ void FakeCrosHealthdService::RunDiskReadRoutine(
|
||||
std::move(callback).Run(run_routine_response_.Clone());
|
||||
}
|
||||
|
||||
void FakeCrosHealthdService::RunPrimeSearchRoutine(
|
||||
uint32_t length_seconds,
|
||||
uint64_t max_num,
|
||||
RunPrimeSearchRoutineCallback callback) {
|
||||
std::move(callback).Run(run_routine_response_.Clone());
|
||||
}
|
||||
|
||||
void FakeCrosHealthdService::ProbeTelemetryInfo(
|
||||
const std::vector<mojom::ProbeCategoryEnum>& categories,
|
||||
ProbeTelemetryInfoCallback callback) {
|
||||
|
@ -70,6 +70,9 @@ class FakeCrosHealthdService final
|
||||
uint32_t length_seconds,
|
||||
uint32_t file_size_mb,
|
||||
RunDiskReadRoutineCallback callback) override;
|
||||
void RunPrimeSearchRoutine(uint32_t length_seconds,
|
||||
uint64_t max_num,
|
||||
RunPrimeSearchRoutineCallback callback) override;
|
||||
|
||||
// CrosHealthdProbeService overrides:
|
||||
void ProbeTelemetryInfo(
|
||||
|
@ -84,6 +84,11 @@ class ServiceConnectionImpl : public ServiceConnection {
|
||||
uint32_t file_size_mb,
|
||||
mojom::CrosHealthdDiagnosticsService::RunDiskReadRoutineCallback callback)
|
||||
override;
|
||||
void RunPrimeSearchRoutine(
|
||||
base::TimeDelta& exec_duration,
|
||||
uint64_t max_num,
|
||||
mojom::CrosHealthdDiagnosticsService::RunPrimeSearchRoutineCallback
|
||||
callback) override;
|
||||
void ProbeTelemetryInfo(
|
||||
const std::vector<mojom::ProbeCategoryEnum>& categories_to_test,
|
||||
mojom::CrosHealthdProbeService::ProbeTelemetryInfoCallback callback)
|
||||
@ -251,6 +256,17 @@ void ServiceConnectionImpl::RunDiskReadRoutine(
|
||||
type, exec_duration.InSeconds(), file_size_mb, std::move(callback));
|
||||
}
|
||||
|
||||
void ServiceConnectionImpl::RunPrimeSearchRoutine(
|
||||
base::TimeDelta& exec_duration,
|
||||
uint64_t max_num,
|
||||
mojom::CrosHealthdDiagnosticsService::RunPrimeSearchRoutineCallback
|
||||
callback) {
|
||||
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
||||
BindCrosHealthdDiagnosticsServiceIfNeeded();
|
||||
cros_healthd_diagnostics_service_->RunPrimeSearchRoutine(
|
||||
exec_duration.InSeconds(), max_num, std::move(callback));
|
||||
}
|
||||
|
||||
void ServiceConnectionImpl::ProbeTelemetryInfo(
|
||||
const std::vector<mojom::ProbeCategoryEnum>& categories_to_test,
|
||||
mojom::CrosHealthdProbeService::ProbeTelemetryInfoCallback callback) {
|
||||
|
@ -131,6 +131,15 @@ class ServiceConnection {
|
||||
mojom::CrosHealthdDiagnosticsService::RunDiskReadRoutineCallback
|
||||
callback) = 0;
|
||||
|
||||
// Requests that cros_healthd runs the prime search routine. See
|
||||
// src/chromeos/service/cros_healthd/public/mojom/cros_healthd.mojom for
|
||||
// details.
|
||||
virtual void RunPrimeSearchRoutine(
|
||||
base::TimeDelta& exec_duration,
|
||||
uint64_t max_num,
|
||||
mojom::CrosHealthdDiagnosticsService::RunPrimeSearchRoutineCallback
|
||||
callback) = 0;
|
||||
|
||||
// Gather pieces of information about the platform. See
|
||||
// src/chromeos/service/cros_healthd/public/mojom/cros_healthd.mojom for
|
||||
// details.
|
||||
|
@ -385,6 +385,21 @@ TEST_F(CrosHealthdServiceConnectionTest, RunDiskReadRoutine) {
|
||||
run_loop.Run();
|
||||
}
|
||||
|
||||
TEST_F(CrosHealthdServiceConnectionTest, RunPrimeSearchRoutine) {
|
||||
// Test that we can run the prime search routine.
|
||||
auto response = MakeRunRoutineResponse();
|
||||
FakeCrosHealthdClient::Get()->SetRunRoutineResponseForTesting(response);
|
||||
base::RunLoop run_loop;
|
||||
base::TimeDelta exec_duration = base::TimeDelta().FromSeconds(10);
|
||||
ServiceConnection::GetInstance()->RunPrimeSearchRoutine(
|
||||
/*exec_duration=*/exec_duration, /*max_num=*/1000000,
|
||||
base::BindLambdaForTesting([&](mojom::RunRoutineResponsePtr response) {
|
||||
EXPECT_EQ(response, MakeRunRoutineResponse());
|
||||
run_loop.Quit();
|
||||
}));
|
||||
run_loop.Run();
|
||||
}
|
||||
|
||||
TEST_F(CrosHealthdServiceConnectionTest, ProbeTelemetryInfo) {
|
||||
// Test that we can send a request without categories.
|
||||
auto empty_info = mojom::TelemetryInfo::New();
|
||||
|
@ -227,6 +227,24 @@ interface CrosHealthdDiagnosticsService {
|
||||
RunDiskReadRoutine(DiskReadRoutineTypeEnum type, uint32 length_seconds,
|
||||
uint32 file_size_mb)
|
||||
=> (RunRoutineResponse response);
|
||||
|
||||
// Requests that the PrimeSearch routine is created and started on the
|
||||
// platform. Calculate prime numbers between 3 to max_num and verify the
|
||||
// calculation repeatedly in a duration. This routine is only available
|
||||
// if GetAvailableRoutines returned kPrimeSearch.
|
||||
//
|
||||
// The request:
|
||||
// * |length_seconds| - length of time, in seconds, to run the PrimeSearch
|
||||
// routine for. This parameter needs to be strictly
|
||||
// greater than zero.
|
||||
// * |max_num| - largest number that routine will calculate prime numbers up
|
||||
// to.
|
||||
//
|
||||
// The response:
|
||||
// * |response| - contains a unique identifier and status for the created
|
||||
// routine.
|
||||
RunPrimeSearchRoutine(uint32 length_seconds, uint64 max_num)
|
||||
=> (RunRoutineResponse response);
|
||||
};
|
||||
|
||||
// Probe interface exposed by the cros_healthd daemon.
|
||||
|
@ -27,6 +27,7 @@ enum DiagnosticRoutineEnum {
|
||||
kNvmeWearLevel = 8,
|
||||
kNvmeSelfTest = 9,
|
||||
kDiskRead = 10,
|
||||
kPrimeSearch = 11,
|
||||
};
|
||||
|
||||
// Enumeration of the possible DiskRead routine's command type
|
||||
|
Reference in New Issue
Block a user