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 @@
// are not nullable in Mojo.
// 2) Make all fields in BatteryInfo optional in case we want to filter them
// 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;
......@@ -43,6 +48,7 @@ interface ProbeService {
[Extensible]
enum ProbeCategoryEnum {
kBattery,
kNonRemovableBlockDevices,
};
// An enumeration of the different categories of errors that can occur when
......@@ -80,6 +86,13 @@ struct Int64Value {
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,
// wrap uint64 in a struct that can be nulled.
struct UInt64Value {
......@@ -132,6 +145,48 @@ union BatteryResult {
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
// capable of reporting. Note that every field in TelemetryInfo is nullable, and
// the response for a particular ProbeTelemetryInfo request will only contain
......@@ -143,4 +198,8 @@ struct TelemetryInfo {
// Information about the device's main battery. Only present when kBattery was
// included in the categories input to ProbeTelemetryInfo.
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(
switch (input) {
case health::mojom::ProbeCategoryEnum::kBattery:
return cros_healthd::mojom::ProbeCategoryEnum::kBattery;
case health::mojom::ProbeCategoryEnum::kNonRemovableBlockDevices:
return cros_healthd::mojom::ProbeCategoryEnum::kNonRemovableBlockDevices;
}
NOTREACHED();
}
......@@ -59,6 +61,14 @@ health::mojom::Int64ValuePtr Convert(int64_t 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(
cros_healthd::mojom::UInt64ValuePtr input) {
if (!input) {
......@@ -114,6 +124,64 @@ health::mojom::BatteryResultPtr Convert(
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(
cros_healthd::mojom::TelemetryInfoPtr input) {
if (!input) {
......@@ -121,7 +189,8 @@ health::mojom::TelemetryInfoPtr Convert(
}
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
......
......@@ -34,6 +34,10 @@ health::mojom::DoubleValuePtr Convert(double 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(
cros_healthd::mojom::UInt64ValuePtr input);
......@@ -43,6 +47,15 @@ health::mojom::BatteryInfoPtr Convert(
health::mojom::BatteryResultPtr Convert(
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(
cros_healthd::mojom::TelemetryInfoPtr input);
......
......@@ -20,6 +20,9 @@ namespace probe_service_converters {
TEST(ProbeServiceConvertors, ProbeCategoryEnum) {
EXPECT_EQ(Convert(health::mojom::ProbeCategoryEnum::kBattery),
cros_healthd::mojom::ProbeCategoryEnum::kBattery);
EXPECT_EQ(
Convert(health::mojom::ProbeCategoryEnum::kNonRemovableBlockDevices),
cros_healthd::mojom::ProbeCategoryEnum::kNonRemovableBlockDevices);
}
TEST(ProbeServiceConvertors, ProbeCategoryEnumVector) {
......@@ -52,22 +55,27 @@ TEST(ProbeServiceConvertors, ProbeErrorPtr) {
health::mojom::ErrorType::kFileReadError, kMsg));
}
TEST(ProbeServiceConvertors, DoubleValuePtr) {
TEST(ProbeServiceConvertors, DoubleValue) {
constexpr double kValue = 100500.500100;
EXPECT_EQ(Convert(kValue), health::mojom::DoubleValue::New(kValue));
}
TEST(ProbeServiceConvertors, Int64ValuePtr) {
constexpr int64_t kValue = 100500;
TEST(ProbeServiceConvertors, Int64Value) {
constexpr int64_t kValue = -100500;
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) {
EXPECT_TRUE(Convert(cros_healthd::mojom::UInt64ValuePtr()).is_null());
}
TEST(ProbeServiceConvertors, UInt64ValuePtr) {
constexpr uint64_t kValue = -100500;
constexpr uint64_t kValue = 100500;
EXPECT_EQ(Convert(cros_healthd::mojom::UInt64Value::New(kValue)),
health::mojom::UInt64Value::New(kValue));
}
......@@ -144,6 +152,91 @@ TEST(ProbeServiceConvertors, BatteryResultPtrError) {
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) {
constexpr int64_t kCycleCount = 1;
......@@ -169,11 +262,39 @@ TEST(ProbeServiceConvertors, TelemetryInfoPtrHasBatteryResult) {
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) {
const health::mojom::TelemetryInfoPtr telemetry_info_output =
Convert(cros_healthd::mojom::TelemetryInfo::New());
ASSERT_TRUE(telemetry_info_output);
EXPECT_FALSE(telemetry_info_output->battery_result);
EXPECT_FALSE(telemetry_info_output->block_device_result);
}
TEST(ProbeServiceConvertors, TelemetryInfoPtrNull) {
......
......@@ -9,8 +9,8 @@
* @type {!TrustedTypePolicy}
*/
const workerUrlPolicy = trustedTypes.createPolicy(
'telemetry-extension-static',
{createScriptURL: () => 'untrusted_worker.js'});
'telemetry-extension-static',
{createScriptURL: () => 'untrusted_worker.js'});
// Tests that web workers can be spawned from
// chrome-untrusted://telemetry_extension.
......@@ -59,5 +59,7 @@ UNTRUSTED_TEST('UntrustedCanSpawnWorkers', async () => {
UNTRUSTED_TEST('UntustedRequestTelemetryInfo', async () => {
/** @type {!ProbeTelemetryInfoResponse} */
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