Commit 6c9dbe79 authored by Oleh Lamzin's avatar Oleh Lamzin Committed by Commit Bot

[Telemetry SWX] Add non removable block device info

Add non removable block device info to the probe service.

Bug: b:158658869
Change-Id: I6f125a5127372040c884f24a11ac38391beca753
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2268797
Commit-Queue: Oleh Lamzin <lamzin@google.com>
Reviewed-by: default avatarTom Sepez <tsepez@chromium.org>
Reviewed-by: default avatarRoland Bock <rbock@google.com>
Reviewed-by: default avatarGiovanni Ortuño Urquidi <ortuno@chromium.org>
Cr-Commit-Position: refs/heads/master@{#785777}
parent 198db2ac
...@@ -20,6 +20,11 @@ ...@@ -20,6 +20,11 @@
// are not nullable in Mojo. // are not nullable in Mojo.
// 2) Make all fields in BatteryInfo optional in case we want to filter them // 2) Make all fields in BatteryInfo optional in case we want to filter them
// out later. // out later.
// 3) NonRemovableBlockDeviceInfo:
// 3.1) Make all fields in NonRemovableBlockDeviceInfo optional in case we
// want to filter them out later.
// 3.2) Use uint32 to store manufacturer_id instead of uint8 in case we
// want to extend manufacturer range.
module chromeos.health.mojom; module chromeos.health.mojom;
...@@ -43,6 +48,7 @@ interface ProbeService { ...@@ -43,6 +48,7 @@ interface ProbeService {
[Extensible] [Extensible]
enum ProbeCategoryEnum { enum ProbeCategoryEnum {
kBattery, kBattery,
kNonRemovableBlockDevices,
}; };
// An enumeration of the different categories of errors that can occur when // An enumeration of the different categories of errors that can occur when
...@@ -80,6 +86,13 @@ struct Int64Value { ...@@ -80,6 +86,13 @@ struct Int64Value {
int64 value; int64 value;
}; };
// Optional uint32 field. Since primitives numeric types cannot be optional,
// wrap uint32 in a struct that can be nulled.
struct UInt32Value {
// The value of the uint32.
uint32 value;
};
// Optional uint64 field. Since primitives numeric types cannot be optional, // Optional uint64 field. Since primitives numeric types cannot be optional,
// wrap uint64 in a struct that can be nulled. // wrap uint64 in a struct that can be nulled.
struct UInt64Value { struct UInt64Value {
...@@ -132,6 +145,48 @@ union BatteryResult { ...@@ -132,6 +145,48 @@ union BatteryResult {
ProbeError error; ProbeError error;
}; };
// Information related to a specific non-removable block device.
struct NonRemovableBlockDeviceInfo {
// The path of this storage on the system. It is useful if caller needs to
// correlate with other information.
string? path;
// Exact size of this storage, reported in bytes.
UInt64Value? size;
// Storage type, could be MMC / NVMe / ATA, based on udev subsystem.
string? type;
// Manufacturer ID, 8 bits.
UInt32Value? manufacturer_id;
// PNM: Product name, ASCII characters for 6 bytes.
string? name;
// PSN: Product serial number, 32 bits.
UInt32Value? serial;
// Bytes read since last boot.
UInt64Value? bytes_read_since_last_boot;
// Bytes written since last boot.
UInt64Value? bytes_written_since_last_boot;
// Time spent reading since last boot.
UInt64Value? read_time_seconds_since_last_boot;
// Time spent writing since last boot.
UInt64Value? write_time_seconds_since_last_boot;
// Time spent doing I/O since last boot. Counts the time the disk and queue
// were busy, so unlike the fields above, parallel requests are not counted
// multiple times.
UInt64Value? io_time_seconds_since_last_boot;
// Time spent discarding since last boot. Discarding is writing to clear
// blocks which are no longer in use. Supported on kernels 4.18+.
UInt64Value? discard_time_seconds_since_last_boot;
};
// Non-removable block device probe result. Can either be populated with the
// NonRemovableBlockDeviceInfo or an error retrieving the information.
union NonRemovableBlockDeviceResult {
// Valid NonRemovableBlockDeviceInfo.
array<NonRemovableBlockDeviceInfo> block_device_info;
// The error that occurred attempting to retrieve the
// NonRemovableBlockDeviceInfo.
ProbeError error;
};
// A collection of all the device's telemetry information that cros_healthd is // A collection of all the device's telemetry information that cros_healthd is
// capable of reporting. Note that every field in TelemetryInfo is nullable, and // capable of reporting. Note that every field in TelemetryInfo is nullable, and
// the response for a particular ProbeTelemetryInfo request will only contain // the response for a particular ProbeTelemetryInfo request will only contain
...@@ -143,4 +198,8 @@ struct TelemetryInfo { ...@@ -143,4 +198,8 @@ struct TelemetryInfo {
// Information about the device's main battery. Only present when kBattery was // Information about the device's main battery. Only present when kBattery was
// included in the categories input to ProbeTelemetryInfo. // included in the categories input to ProbeTelemetryInfo.
BatteryResult? battery_result; BatteryResult? battery_result;
// Information about all of the device's non-removable block devices. Only
// present when kNonRemovableBlockDevices was included in the categories input
// to ProbeTelemetryInfo.
NonRemovableBlockDeviceResult? block_device_result;
}; };
...@@ -18,6 +18,8 @@ cros_healthd::mojom::ProbeCategoryEnum Convert( ...@@ -18,6 +18,8 @@ cros_healthd::mojom::ProbeCategoryEnum Convert(
switch (input) { switch (input) {
case health::mojom::ProbeCategoryEnum::kBattery: case health::mojom::ProbeCategoryEnum::kBattery:
return cros_healthd::mojom::ProbeCategoryEnum::kBattery; return cros_healthd::mojom::ProbeCategoryEnum::kBattery;
case health::mojom::ProbeCategoryEnum::kNonRemovableBlockDevices:
return cros_healthd::mojom::ProbeCategoryEnum::kNonRemovableBlockDevices;
} }
NOTREACHED(); NOTREACHED();
} }
...@@ -59,6 +61,14 @@ health::mojom::Int64ValuePtr Convert(int64_t input) { ...@@ -59,6 +61,14 @@ health::mojom::Int64ValuePtr Convert(int64_t input) {
return health::mojom::Int64Value::New(input); return health::mojom::Int64Value::New(input);
} }
health::mojom::UInt32ValuePtr Convert(uint32_t input) {
return health::mojom::UInt32Value::New(input);
}
health::mojom::UInt64ValuePtr Convert(uint64_t input) {
return health::mojom::UInt64Value::New(input);
}
health::mojom::UInt64ValuePtr Convert( health::mojom::UInt64ValuePtr Convert(
cros_healthd::mojom::UInt64ValuePtr input) { cros_healthd::mojom::UInt64ValuePtr input) {
if (!input) { if (!input) {
...@@ -114,6 +124,64 @@ health::mojom::BatteryResultPtr Convert( ...@@ -114,6 +124,64 @@ health::mojom::BatteryResultPtr Convert(
return output; return output;
} }
health::mojom::NonRemovableBlockDeviceInfoPtr Convert(
cros_healthd::mojom::NonRemovableBlockDeviceInfoPtr input) {
DCHECK(input) << "NonRemovableBlockDeviceInfoPtr must never be nullptr since "
"its always item in the array, so originally array must not "
"contain nullptr items.";
auto output = health::mojom::NonRemovableBlockDeviceInfo::New();
output->path = std::move(input->path);
output->size = Convert(input->size);
output->type = std::move(input->type);
output->manufacturer_id =
Convert(static_cast<uint32_t>(input->manufacturer_id));
output->name = std::move(input->name);
output->serial = Convert(static_cast<uint32_t>(input->serial));
output->bytes_read_since_last_boot =
Convert(input->bytes_read_since_last_boot);
output->bytes_written_since_last_boot =
Convert(input->bytes_written_since_last_boot);
output->read_time_seconds_since_last_boot =
Convert(input->read_time_seconds_since_last_boot);
output->write_time_seconds_since_last_boot =
Convert(input->write_time_seconds_since_last_boot);
output->io_time_seconds_since_last_boot =
Convert(input->io_time_seconds_since_last_boot);
output->discard_time_seconds_since_last_boot =
Convert(std::move(input->discard_time_seconds_since_last_boot));
return output;
}
std::vector<health::mojom::NonRemovableBlockDeviceInfoPtr> Convert(
std::vector<cros_healthd::mojom::NonRemovableBlockDeviceInfoPtr> input) {
std::vector<health::mojom::NonRemovableBlockDeviceInfoPtr> output;
for (size_t i = 0; i < input.size(); ++i) {
output.push_back(Convert(std::move(input[i])));
}
return output;
}
health::mojom::NonRemovableBlockDeviceResultPtr Convert(
cros_healthd::mojom::NonRemovableBlockDeviceResultPtr input) {
if (!input) {
return nullptr;
}
auto output = health::mojom::NonRemovableBlockDeviceResult::New();
if (input->is_error()) {
output->set_error(Convert(std::move(input->get_error())));
} else if (input->is_block_device_info()) {
output->set_block_device_info(
Convert(std::move(input->get_block_device_info())));
}
return output;
}
health::mojom::TelemetryInfoPtr Convert( health::mojom::TelemetryInfoPtr Convert(
cros_healthd::mojom::TelemetryInfoPtr input) { cros_healthd::mojom::TelemetryInfoPtr input) {
if (!input) { if (!input) {
...@@ -121,7 +189,8 @@ health::mojom::TelemetryInfoPtr Convert( ...@@ -121,7 +189,8 @@ health::mojom::TelemetryInfoPtr Convert(
} }
return health::mojom::TelemetryInfo::New( return health::mojom::TelemetryInfo::New(
Convert(std::move(input->battery_result))); Convert(std::move(input->battery_result)),
Convert(std::move(input->block_device_result)));
} }
} // namespace probe_service_converters } // namespace probe_service_converters
......
...@@ -34,6 +34,10 @@ health::mojom::DoubleValuePtr Convert(double input); ...@@ -34,6 +34,10 @@ health::mojom::DoubleValuePtr Convert(double input);
health::mojom::Int64ValuePtr Convert(int64_t input); health::mojom::Int64ValuePtr Convert(int64_t input);
health::mojom::UInt32ValuePtr Convert(uint32_t input);
health::mojom::UInt64ValuePtr Convert(uint64_t input);
health::mojom::UInt64ValuePtr Convert( health::mojom::UInt64ValuePtr Convert(
cros_healthd::mojom::UInt64ValuePtr input); cros_healthd::mojom::UInt64ValuePtr input);
...@@ -43,6 +47,15 @@ health::mojom::BatteryInfoPtr Convert( ...@@ -43,6 +47,15 @@ health::mojom::BatteryInfoPtr Convert(
health::mojom::BatteryResultPtr Convert( health::mojom::BatteryResultPtr Convert(
cros_healthd::mojom::BatteryResultPtr input); cros_healthd::mojom::BatteryResultPtr input);
health::mojom::NonRemovableBlockDeviceInfoPtr Convert(
cros_healthd::mojom::NonRemovableBlockDeviceInfoPtr input);
std::vector<health::mojom::NonRemovableBlockDeviceInfoPtr> Convert(
std::vector<cros_healthd::mojom::NonRemovableBlockDeviceInfoPtr> input);
health::mojom::NonRemovableBlockDeviceResultPtr Convert(
cros_healthd::mojom::NonRemovableBlockDeviceResultPtr input);
health::mojom::TelemetryInfoPtr Convert( health::mojom::TelemetryInfoPtr Convert(
cros_healthd::mojom::TelemetryInfoPtr input); cros_healthd::mojom::TelemetryInfoPtr input);
......
...@@ -20,6 +20,9 @@ namespace probe_service_converters { ...@@ -20,6 +20,9 @@ namespace probe_service_converters {
TEST(ProbeServiceConvertors, ProbeCategoryEnum) { TEST(ProbeServiceConvertors, ProbeCategoryEnum) {
EXPECT_EQ(Convert(health::mojom::ProbeCategoryEnum::kBattery), EXPECT_EQ(Convert(health::mojom::ProbeCategoryEnum::kBattery),
cros_healthd::mojom::ProbeCategoryEnum::kBattery); cros_healthd::mojom::ProbeCategoryEnum::kBattery);
EXPECT_EQ(
Convert(health::mojom::ProbeCategoryEnum::kNonRemovableBlockDevices),
cros_healthd::mojom::ProbeCategoryEnum::kNonRemovableBlockDevices);
} }
TEST(ProbeServiceConvertors, ProbeCategoryEnumVector) { TEST(ProbeServiceConvertors, ProbeCategoryEnumVector) {
...@@ -52,22 +55,27 @@ TEST(ProbeServiceConvertors, ProbeErrorPtr) { ...@@ -52,22 +55,27 @@ TEST(ProbeServiceConvertors, ProbeErrorPtr) {
health::mojom::ErrorType::kFileReadError, kMsg)); health::mojom::ErrorType::kFileReadError, kMsg));
} }
TEST(ProbeServiceConvertors, DoubleValuePtr) { TEST(ProbeServiceConvertors, DoubleValue) {
constexpr double kValue = 100500.500100; constexpr double kValue = 100500.500100;
EXPECT_EQ(Convert(kValue), health::mojom::DoubleValue::New(kValue)); EXPECT_EQ(Convert(kValue), health::mojom::DoubleValue::New(kValue));
} }
TEST(ProbeServiceConvertors, Int64ValuePtr) { TEST(ProbeServiceConvertors, Int64Value) {
constexpr int64_t kValue = 100500; constexpr int64_t kValue = -100500;
EXPECT_EQ(Convert(kValue), health::mojom::Int64Value::New(kValue)); EXPECT_EQ(Convert(kValue), health::mojom::Int64Value::New(kValue));
} }
TEST(ProbeServiceConvertors, UInt64Value) {
constexpr uint64_t kValue = 100500;
EXPECT_EQ(Convert(kValue), health::mojom::UInt64Value::New(kValue));
}
TEST(ProbeServiceConvertors, UInt64ValuePtrNull) { TEST(ProbeServiceConvertors, UInt64ValuePtrNull) {
EXPECT_TRUE(Convert(cros_healthd::mojom::UInt64ValuePtr()).is_null()); EXPECT_TRUE(Convert(cros_healthd::mojom::UInt64ValuePtr()).is_null());
} }
TEST(ProbeServiceConvertors, UInt64ValuePtr) { TEST(ProbeServiceConvertors, UInt64ValuePtr) {
constexpr uint64_t kValue = -100500; constexpr uint64_t kValue = 100500;
EXPECT_EQ(Convert(cros_healthd::mojom::UInt64Value::New(kValue)), EXPECT_EQ(Convert(cros_healthd::mojom::UInt64Value::New(kValue)),
health::mojom::UInt64Value::New(kValue)); health::mojom::UInt64Value::New(kValue));
} }
...@@ -144,6 +152,91 @@ TEST(ProbeServiceConvertors, BatteryResultPtrError) { ...@@ -144,6 +152,91 @@ TEST(ProbeServiceConvertors, BatteryResultPtrError) {
EXPECT_TRUE(ptr->is_error()); EXPECT_TRUE(ptr->is_error());
} }
TEST(ProbeServiceConvertors, NonRemovableBlockDeviceInfoPtr) {
constexpr char kPath[] = "/dev/device1";
constexpr uint64_t kSize = 1000000000;
constexpr char kType[] = "NVMe";
constexpr uint8_t kManufacturerId = 200;
constexpr char kName[] = "goog";
constexpr uint32_t kSerial = 0xaabbccdd;
constexpr uint64_t kBytesReadSinceLastBoot = 10;
constexpr uint64_t kBytesWrittenSinceLastBoot = 100;
constexpr uint64_t kReadTimeSecondsSinceLastBoot = 1000;
constexpr uint64_t kWriteTimeSecondsSinceLastBoot = 10000;
constexpr uint64_t kIoTimeSecondsSinceLastBoot = 100000;
constexpr uint64_t kDiscardTimeSecondsSinceLastBoot = 1000000;
// Here we don't use cros_healthd::mojom::NonRemovableBlockDeviceInfoPtr::New
// because NonRemovableBlockDeviceInfoPtr may contain some fields that we
// don't use yet.
auto info = cros_healthd::mojom::NonRemovableBlockDeviceInfo::New();
info->path = kPath;
info->size = kSize;
info->type = kType;
info->manufacturer_id = kManufacturerId;
info->name = kName;
info->serial = kSerial;
info->bytes_read_since_last_boot = kBytesReadSinceLastBoot;
info->bytes_written_since_last_boot = kBytesWrittenSinceLastBoot;
info->read_time_seconds_since_last_boot = kReadTimeSecondsSinceLastBoot;
info->write_time_seconds_since_last_boot = kWriteTimeSecondsSinceLastBoot;
info->io_time_seconds_since_last_boot = kIoTimeSecondsSinceLastBoot;
info->discard_time_seconds_since_last_boot =
cros_healthd::mojom::UInt64Value::New(kDiscardTimeSecondsSinceLastBoot);
// Here we intentionaly use health::mojom::NonRemovableBlockDeviceInfoPtr::New
// to don't forget to test new fields.
EXPECT_EQ(
Convert(info.Clone()),
health::mojom::NonRemovableBlockDeviceInfo::New(
kPath, health::mojom::UInt64Value::New(kSize), kType,
health::mojom::UInt32Value::New(kManufacturerId), kName,
health::mojom::UInt32Value::New(kSerial),
health::mojom::UInt64Value::New(kBytesReadSinceLastBoot),
health::mojom::UInt64Value::New(kBytesWrittenSinceLastBoot),
health::mojom::UInt64Value::New(kReadTimeSecondsSinceLastBoot),
health::mojom::UInt64Value::New(kWriteTimeSecondsSinceLastBoot),
health::mojom::UInt64Value::New(kIoTimeSecondsSinceLastBoot),
health::mojom::UInt64Value::New(kDiscardTimeSecondsSinceLastBoot)));
}
TEST(ProbeServiceConvertors, NonRemovableBlockDeviceResultPtrNull) {
EXPECT_TRUE(Convert(cros_healthd::mojom::NonRemovableBlockDeviceResultPtr())
.is_null());
}
TEST(ProbeServiceConvertors, NonRemovableBlockDeviceResultPtrInfo) {
constexpr char kPath1[] = "Path1";
constexpr char kPath2[] = "Path2";
auto info1 = cros_healthd::mojom::NonRemovableBlockDeviceInfo::New();
info1->path = kPath1;
auto info2 = cros_healthd::mojom::NonRemovableBlockDeviceInfo::New();
info2->path = kPath2;
std::vector<cros_healthd::mojom::NonRemovableBlockDeviceInfoPtr> infos;
infos.push_back(std::move(info1));
infos.push_back(std::move(info2));
const health::mojom::NonRemovableBlockDeviceResultPtr ptr = Convert(
cros_healthd::mojom::NonRemovableBlockDeviceResult::NewBlockDeviceInfo(
std::move(infos)));
ASSERT_TRUE(ptr);
EXPECT_TRUE(ptr->is_block_device_info());
ASSERT_EQ(ptr->get_block_device_info().size(), 2ULL);
EXPECT_EQ((ptr->get_block_device_info())[0]->path, kPath1);
EXPECT_EQ((ptr->get_block_device_info())[1]->path, kPath2);
}
TEST(ProbeServiceConvertors, NonRemovableBlockDeviceResultPtrError) {
const health::mojom::NonRemovableBlockDeviceResultPtr ptr = Convert(
cros_healthd::mojom::NonRemovableBlockDeviceResult::NewError(nullptr));
ASSERT_TRUE(ptr);
EXPECT_TRUE(ptr->is_error());
}
TEST(ProbeServiceConvertors, TelemetryInfoPtrHasBatteryResult) { TEST(ProbeServiceConvertors, TelemetryInfoPtrHasBatteryResult) {
constexpr int64_t kCycleCount = 1; constexpr int64_t kCycleCount = 1;
...@@ -169,11 +262,39 @@ TEST(ProbeServiceConvertors, TelemetryInfoPtrHasBatteryResult) { ...@@ -169,11 +262,39 @@ TEST(ProbeServiceConvertors, TelemetryInfoPtrHasBatteryResult) {
kCycleCount); kCycleCount);
} }
TEST(ProbeServiceConvertors, TelemetryInfoPtrHasBlockDeviceResult) {
constexpr uint64_t kSize = 10000000;
auto device_info = cros_healthd::mojom::NonRemovableBlockDeviceInfo::New();
device_info->size = kSize;
std::vector<cros_healthd::mojom::NonRemovableBlockDeviceInfoPtr> device_infos;
device_infos.push_back(std::move(device_info));
auto input = cros_healthd::mojom::TelemetryInfo::New();
input->block_device_result =
cros_healthd::mojom::NonRemovableBlockDeviceResult::NewBlockDeviceInfo(
std::move(device_infos));
const health::mojom::TelemetryInfoPtr output = Convert(std::move(input));
ASSERT_TRUE(output);
ASSERT_TRUE(output->block_device_result);
ASSERT_TRUE(output->block_device_result->is_block_device_info());
const auto& device_info_output =
output->block_device_result->get_block_device_info();
ASSERT_EQ(device_info_output.size(), 1ULL);
ASSERT_TRUE(device_info_output[0]);
ASSERT_TRUE(device_info_output[0]->size);
EXPECT_EQ(device_info_output[0]->size->value, kSize);
}
TEST(ProbeServiceConvertors, TelemetryInfoPtrWithNullFields) { TEST(ProbeServiceConvertors, TelemetryInfoPtrWithNullFields) {
const health::mojom::TelemetryInfoPtr telemetry_info_output = const health::mojom::TelemetryInfoPtr telemetry_info_output =
Convert(cros_healthd::mojom::TelemetryInfo::New()); Convert(cros_healthd::mojom::TelemetryInfo::New());
ASSERT_TRUE(telemetry_info_output); ASSERT_TRUE(telemetry_info_output);
EXPECT_FALSE(telemetry_info_output->battery_result); EXPECT_FALSE(telemetry_info_output->battery_result);
EXPECT_FALSE(telemetry_info_output->block_device_result);
} }
TEST(ProbeServiceConvertors, TelemetryInfoPtrNull) { TEST(ProbeServiceConvertors, TelemetryInfoPtrNull) {
......
...@@ -59,5 +59,7 @@ UNTRUSTED_TEST('UntrustedCanSpawnWorkers', async () => { ...@@ -59,5 +59,7 @@ UNTRUSTED_TEST('UntrustedCanSpawnWorkers', async () => {
UNTRUSTED_TEST('UntustedRequestTelemetryInfo', async () => { UNTRUSTED_TEST('UntustedRequestTelemetryInfo', async () => {
/** @type {!ProbeTelemetryInfoResponse} */ /** @type {!ProbeTelemetryInfoResponse} */
const response = await requestTelemetryInfo(); const response = await requestTelemetryInfo();
assertDeepEquals(response, {'telemetryInfo': {'batteryResult': null}}); assertDeepEquals(
response,
{'telemetryInfo': {'batteryResult': null, 'blockDeviceResult': null}});
}); });
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment