// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ash/system_logs/reven_log_source.h"
#include <optional>
#include "base/strings/strcat.h"
#include "base/strings/string_number_conversions.h"
#include "base/test/task_environment.h"
#include "base/time/time.h"
#include "chromeos/ash/components/mojo_service_manager/fake_mojo_service_manager.h"
#include "chromeos/ash/services/cros_healthd/public/cpp/fake_cros_healthd.h"
#include "chromeos/ash/services/cros_healthd/public/mojom/cros_healthd.mojom.h"
#include "chromeos/ash/services/cros_healthd/public/mojom/cros_healthd_probe.mojom-shared.h"
#include "chromeos/ash/services/cros_healthd/public/mojom/cros_healthd_probe.mojom.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace system_logs {
namespace {
namespace healthd = ::ash::cros_healthd::mojom;
using ::testing::HasSubstr;
constexpr char kRevenAvailableMemoryKey[] = "chromeosflex_available_memory";
constexpr char kRevenBiosVersionKey[] = "chromeosflex_bios_version";
constexpr char kRevenBluetoothDriverKey[] = "chromeosflex_bluetooth_driver";
constexpr char kRevenBluetoothIdKey[] = "chromeosflex_bluetooth_id";
constexpr char kRevenBluetoothNameKey[] = "chromeosflex_bluetooth_name";
constexpr char kRevenCpuNameKey[] = "chromeosflex_cpu_name";
constexpr char kRevenEthernetDriverKey[] = "chromeosflex_ethernet_driver";
constexpr char kRevenEthernetIdKey[] = "chromeosflex_ethernet_id";
constexpr char kRevenEthernetNameKey[] = "chromeosflex_ethernet_name";
constexpr char kRevenFreeMemoryKey[] = "chromeosflex_free_memory";
constexpr char kRevenGlExtensionsKey[] = "chromeosflex_gl_extensions";
constexpr char kRevenGlRendererKey[] = "chromeosflex_gl_renderer";
constexpr char kRevenGlShadingVersionKey[] = "chromeosflex_gl_shading_version";
constexpr char kRevenGlVendorKey[] = "chromeosflex_gl_vendor";
constexpr char kRevenGlVersionKey[] = "chromeosflex_gl_version";
constexpr char kRevenGpuDriverKey[] = "chromeosflex_gpu_driver";
constexpr char kRevenGpuIdKey[] = "chromeosflex_gpu_id";
constexpr char kRevenGpuNameKey[] = "chromeosflex_gpu_name";
constexpr char kRevenProductNameKey[] = "chromeosflex_product_name";
constexpr char kRevenProductVendorKey[] = "chromeosflex_product_vendor";
constexpr char kRevenProductVersionKey[] = "chromeosflex_product_version";
constexpr char kRevenSecurebootKey[] = "chromeosflex_secureboot";
constexpr char kRevenTotalMemoryKey[] = "chromeosflex_total_memory";
constexpr char kRevenTouchpadStack[] = "chromeosflex_touchpad";
constexpr char kRevenTpmAllowListedKey[] = "chromeosflex_tpm_allow_listed";
constexpr char kRevenTpmDidVidKey[] = "chromeosflex_tpm_did_vid";
constexpr char kRevenTpmManufacturerKey[] = "chromeosflex_tpm_manufacturer";
constexpr char kRevenTpmOwnedKey[] = "chromeosflex_tpm_owned";
constexpr char kRevenTpmSpecLevelKey[] = "chromeosflex_tpm_spec_level";
constexpr char kRevenTpmVersionKey[] = "chromeosflex_tpm_version";
constexpr char kRevenUefiKey[] = "chromeosflex_uefi";
constexpr char kRevenWirelessDriverKey[] = "chromeosflex_wireless_driver";
constexpr char kRevenWirelessIdKey[] = "chromeosflex_wireless_id";
constexpr char kRevenWirelessNameKey[] = "chromeosflex_wireless_name";
constexpr char kCpuNameVal[] = "Intel(R) Core(TM) i5-10210U CPU @ 1.60GHz";
constexpr int kTotalMemory = 2048;
constexpr int kFreeMemory = 1024;
constexpr int kAvailableMemory = 512;
void SetCpuInfo(healthd::TelemetryInfoPtr& telemetry_info) {
auto cpu_info = healthd::CpuInfo::New();
auto physical_cpu_info = healthd::PhysicalCpuInfo::New();
auto logical_cpu_info = healthd::LogicalCpuInfo::New();
physical_cpu_info->logical_cpus.push_back(std::move(logical_cpu_info));
physical_cpu_info->model_name = kCpuNameVal;
cpu_info->num_total_threads = 2;
cpu_info->physical_cpus.emplace_back(std::move(physical_cpu_info));
telemetry_info->cpu_result =
healthd::CpuResult::NewCpuInfo(std::move(cpu_info));
}
void SetCpuInfoWithProbeError(healthd::TelemetryInfoPtr& telemetry_info) {
auto probe_error =
healthd::ProbeError::New(healthd::ErrorType::kFileReadError, "");
telemetry_info->cpu_result =
healthd::CpuResult::NewError(std::move(probe_error));
}
void SetMemoryInfo(healthd::TelemetryInfoPtr& telemetry_info) {
auto memory_info =
healthd::MemoryInfo::New(kTotalMemory, kFreeMemory, kAvailableMemory, 0);
telemetry_info->memory_result =
healthd::MemoryResult::NewMemoryInfo(std::move(memory_info));
}
void SetMemoryInfoWithProbeError(healthd::TelemetryInfoPtr& telemetry_info) {
auto probe_error =
healthd::ProbeError::New(healthd::ErrorType::kFileReadError, "");
telemetry_info->memory_result =
healthd::MemoryResult::NewError(std::move(probe_error));
}
void SetSystemInfo(healthd::TelemetryInfoPtr& telemetry_info,
healthd::OsInfoPtr os_info,
healthd::DmiInfoPtr dmi_info) {
auto system_info = healthd::SystemInfo::New();
if (os_info) {
system_info->os_info = std::move(os_info);
}
if (dmi_info) {
system_info->dmi_info = std::move(dmi_info);
}
telemetry_info->system_result =
healthd::SystemResult::NewSystemInfo(std::move(system_info));
}
healthd::OsInfoPtr CreateOsInfo(healthd::BootMode boot_mode) {
healthd::OsInfoPtr os_info = healthd::OsInfo::New();
os_info->os_version = healthd::OsVersion::New();
os_info->boot_mode = boot_mode;
return os_info;
}
healthd::DmiInfoPtr CreateDmiInfo() {
healthd::DmiInfoPtr dmi_info = healthd::DmiInfo::New();
dmi_info->sys_vendor = std::optional<std::string>("LENOVO");
dmi_info->product_name = std::optional<std::string>("20U9001PUS");
dmi_info->product_version =
std::optional<std::string>("ThinkPad X1 Carbon Gen 8");
dmi_info->bios_version = std::optional<std::string>("N2WET26W (1.16 )");
return dmi_info;
}
healthd::BusDevicePtr CreatePciDevice(healthd::BusDeviceClass device_class,
const std::string& vendor_name,
const std::string& product_name,
const std::string& driver,
uint16_t vendor_id,
uint16_t device_id) {
auto device = healthd::BusDevice::New();
device->device_class = device_class;
device->vendor_name = vendor_name;
device->product_name = product_name;
auto pci_info = healthd::PciBusInfo::New();
pci_info->vendor_id = vendor_id;
pci_info->device_id = device_id;
if (driver != "") {
pci_info->driver = std::optional<std::string>(driver);
}
device->bus_info = healthd::BusInfo::NewPciBusInfo(std::move(pci_info));
return device;
}
void SetPciEthernetDevices(healthd::TelemetryInfoPtr& telemetry_info) {
std::vector<healthd::BusDevicePtr> bus_devices;
bus_devices.push_back(
CreatePciDevice(healthd::BusDeviceClass::kEthernetController, "intel",
"product1", "driver1", 0x12ab, 0x34cd));
bus_devices.push_back(
CreatePciDevice(healthd::BusDeviceClass::kEthernetController, "broadcom",
"product2", "", 0x56ab, 0x78cd));
telemetry_info->bus_result =
healthd::BusResult::NewBusDevices(std::move(bus_devices));
}
void SetPciWirelessDevices(healthd::TelemetryInfoPtr& telemetry_info) {
std::vector<healthd::BusDevicePtr> bus_devices;
bus_devices.push_back(
CreatePciDevice(healthd::BusDeviceClass::kWirelessController, "intel",
"wireless_product1", "wireless_driver1", 0x12ab, 0x34cd));
bus_devices.push_back(
CreatePciDevice(healthd::BusDeviceClass::kWirelessController, "broadcom",
"wireless_product2", "", 0x56ab, 0x78cd));
telemetry_info->bus_result =
healthd::BusResult::NewBusDevices(std::move(bus_devices));
}
void SetPciBluetoothDevices(healthd::TelemetryInfoPtr& telemetry_info) {
std::vector<healthd::BusDevicePtr> bus_devices;
bus_devices.push_back(CreatePciDevice(
healthd::BusDeviceClass::kBluetoothAdapter, "intel", "bluetooth_product1",
"bluetooth_driver1", 0x12ab, 0x34cd));
bus_devices.push_back(
CreatePciDevice(healthd::BusDeviceClass::kBluetoothAdapter, "broadcom",
"bluetooth_product2", "", 0x56ab, 0x78cd));
telemetry_info->bus_result =
healthd::BusResult::NewBusDevices(std::move(bus_devices));
}
void SetPciDisplayDevices(healthd::TelemetryInfoPtr& telemetry_info) {
std::vector<healthd::BusDevicePtr> bus_devices;
bus_devices.push_back(
CreatePciDevice(healthd::BusDeviceClass::kDisplayController, "intel",
"945GM", "driver1", 0x12ab, 0x34cd));
telemetry_info->bus_result =
healthd::BusResult::NewBusDevices(std::move(bus_devices));
}
healthd::BusDevicePtr CreateUsbDevice(healthd::BusDeviceClass device_class,
const std::string& vendor_name,
const std::string& product_name,
const std::string& driver,
uint16_t vendor_id,
uint16_t product_id) {
auto device = healthd::BusDevice::New();
device->device_class = device_class;
device->vendor_name = vendor_name;
device->product_name = product_name;
auto usb_info = healthd::UsbBusInfo::New();
usb_info->vendor_id = vendor_id;
usb_info->product_id = product_id;
auto usb_if_info = healthd::UsbBusInterfaceInfo::New();
if (driver != "") {
usb_if_info->driver = std::optional<std::string>(driver);
}
usb_info->interfaces.push_back(std::move(usb_if_info));
device->bus_info = healthd::BusInfo::NewUsbBusInfo(std::move(usb_info));
return device;
}
void SetUsbEthernetDevices(healthd::TelemetryInfoPtr& telemetry_info) {
std::vector<healthd::BusDevicePtr> bus_devices;
bus_devices.push_back(
CreateUsbDevice(healthd::BusDeviceClass::kEthernetController, "intel",
"product1", "driver1", 0x12ab, 0x34cd));
bus_devices.push_back(
CreateUsbDevice(healthd::BusDeviceClass::kEthernetController, "broadcom",
"product2", "", 0x56ab, 0x78cd));
telemetry_info->bus_result =
healthd::BusResult::NewBusDevices(std::move(bus_devices));
}
void SetUsbWirelessDevices(healthd::TelemetryInfoPtr& telemetry_info) {
std::vector<healthd::BusDevicePtr> bus_devices;
bus_devices.push_back(
CreateUsbDevice(healthd::BusDeviceClass::kWirelessController, "intel",
"wireless_product1", "wireless_driver1", 0x12ab, 0x34cd));
bus_devices.push_back(
CreateUsbDevice(healthd::BusDeviceClass::kWirelessController, "broadcom",
"wireless_product2", "", 0x56ab, 0x78cd));
telemetry_info->bus_result =
healthd::BusResult::NewBusDevices(std::move(bus_devices));
}
void SetUsbBluetoothDevices(healthd::TelemetryInfoPtr& telemetry_info) {
std::vector<healthd::BusDevicePtr> bus_devices;
bus_devices.push_back(CreateUsbDevice(
healthd::BusDeviceClass::kBluetoothAdapter, "intel", "bluetooth_product1",
"bluetooth_driver1", 0x12ab, 0x34cd));
bus_devices.push_back(
CreateUsbDevice(healthd::BusDeviceClass::kBluetoothAdapter, "broadcom",
"bluetooth_product2", "", 0x56ab, 0x78cd));
telemetry_info->bus_result =
healthd::BusResult::NewBusDevices(std::move(bus_devices));
}
void SetUsbDisplayDevices(healthd::TelemetryInfoPtr& telemetry_info) {
std::vector<healthd::BusDevicePtr> bus_devices;
bus_devices.push_back(
CreateUsbDevice(healthd::BusDeviceClass::kDisplayController, "intel",
"product1", "driver1", 0x12ab, 0x34cd));
telemetry_info->bus_result =
healthd::BusResult::NewBusDevices(std::move(bus_devices));
}
void SetTpmInfo(healthd::TelemetryInfoPtr& telemetry_info,
const std::string& did_vid,
uint32_t family,
bool is_owned,
bool is_allowed) {
auto version = healthd::TpmVersion::New();
version->family = family;
version->manufacturer = 1129467731;
version->spec_level = 116;
auto status = healthd::TpmStatus::New();
status->owned = is_owned;
auto dictionary_attack = healthd::TpmDictionaryAttack::New();
auto attestation = healthd::TpmAttestation::New();
auto supported_features = healthd::TpmSupportedFeatures::New();
supported_features->is_allowed = is_allowed;
healthd::TpmInfoPtr tpm_info = healthd::TpmInfo::New();
if (did_vid != "") {
tpm_info->did_vid = std::optional<std::string>(did_vid);
}
tpm_info->version = std::move(version);
tpm_info->status = std::move(status);
tpm_info->dictionary_attack = std::move(dictionary_attack);
tpm_info->attestation = std::move(attestation);
tpm_info->supported_features = std::move(supported_features);
telemetry_info->tpm_result =
healthd::TpmResult::NewTpmInfo(std::move(tpm_info));
}
void SetGraphicsInfo(healthd::TelemetryInfoPtr& telemetry_info,
std::vector<std::string>& gl_extensions) {
auto gles_info = healthd::GLESInfo::New();
gles_info->version = "fake_version";
gles_info->shading_version = "fake_shading_version";
gles_info->vendor = "fake_vendor";
gles_info->renderer = "fake_renderer";
gles_info->extensions = gl_extensions;
healthd::GraphicsInfoPtr graphics_info = healthd::GraphicsInfo::New();
graphics_info->gles_info = std::move(gles_info);
auto egl_info = healthd::EGLInfo::New();
graphics_info->egl_info = std::move(egl_info);
telemetry_info->graphics_result =
healthd::GraphicsResult::NewGraphicsInfo(std::move(graphics_info));
}
} // namespace
class RevenLogSourceTest : public ::testing::Test {
public:
RevenLogSourceTest() {
ash::cros_healthd::FakeCrosHealthd::Initialize();
source_ = std::make_unique<RevenLogSource>();
}
~RevenLogSourceTest() override {
source_.reset();
ash::cros_healthd::FakeCrosHealthd::Shutdown();
base::RunLoop().RunUntilIdle();
}
std::unique_ptr<SystemLogsResponse> Fetch() {
std::unique_ptr<SystemLogsResponse> result;
base::RunLoop run_loop;
source_->Fetch(base::BindOnce(
[](std::unique_ptr<SystemLogsResponse>* result,
base::OnceClosure quit_closure,
std::unique_ptr<SystemLogsResponse> response) {
*result = std::move(response);
std::move(quit_closure).Run();
},
&result, run_loop.QuitClosure()));
run_loop.Run();
return result;
}
void SetBootModeInfo(healthd::BootMode boot_mode) {
auto info = healthd::TelemetryInfo::New();
auto os_info = CreateOsInfo(boot_mode);
auto dmi_info = CreateDmiInfo();
SetSystemInfo(info, std::move(os_info), std::move(dmi_info));
ash::cros_healthd::FakeCrosHealthd::Get()
->SetProbeTelemetryInfoResponseForTesting(info);
}
void VerifyOutputContains(const std::unique_ptr<SystemLogsResponse>& response,
const std::string& key,
const std::string& expected_output) {
ASSERT_NE(response, nullptr);
const auto response_iter = response->find(key);
ASSERT_NE(response_iter, response->end());
EXPECT_THAT(response_iter->second, HasSubstr(expected_output));
}
protected:
base::test::TaskEnvironment task_environment_{
base::test::TaskEnvironment::TimeSource::MOCK_TIME};
::ash::mojo_service_manager::FakeMojoServiceManager fake_service_manager_;
std::unique_ptr<RevenLogSource> source_;
};
TEST_F(RevenLogSourceTest, FetchCpuInfoSuccess) {
auto info = healthd::TelemetryInfo::New();
SetCpuInfo(info);
ash::cros_healthd::FakeCrosHealthd::Get()
->SetProbeTelemetryInfoResponseForTesting(info);
const std::unique_ptr<SystemLogsResponse> response = Fetch();
VerifyOutputContains(response, kRevenCpuNameKey,
"Intel(R) Core(TM) i5-10210U CPU @ 1.60GHz");
}
TEST_F(RevenLogSourceTest, FetchCpuInfoFailure) {
auto info = healthd::TelemetryInfo::New();
SetCpuInfoWithProbeError(info);
ash::cros_healthd::FakeCrosHealthd::Get()
->SetProbeTelemetryInfoResponseForTesting(info);
VerifyOutputContains(Fetch(), kRevenCpuNameKey, "<not available>");
}
TEST_F(RevenLogSourceTest, FetchMemoryInfoSuccess) {
auto info = healthd::TelemetryInfo::New();
SetMemoryInfo(info);
ash::cros_healthd::FakeCrosHealthd::Get()
->SetProbeTelemetryInfoResponseForTesting(info);
const std::unique_ptr<SystemLogsResponse> response = Fetch();
VerifyOutputContains(response, kRevenTotalMemoryKey, "2048");
VerifyOutputContains(response, kRevenFreeMemoryKey, "1024");
VerifyOutputContains(response, kRevenAvailableMemoryKey, "512");
}
TEST_F(RevenLogSourceTest, FetchMemoryInfoFailure) {
auto info = healthd::TelemetryInfo::New();
SetMemoryInfoWithProbeError(info);
ash::cros_healthd::FakeCrosHealthd::Get()
->SetProbeTelemetryInfoResponseForTesting(info);
const std::unique_ptr<SystemLogsResponse> response = Fetch();
const std::string not_available = "<not available>";
VerifyOutputContains(response, kRevenTotalMemoryKey, not_available);
VerifyOutputContains(response, kRevenFreeMemoryKey, not_available);
VerifyOutputContains(response, kRevenAvailableMemoryKey, not_available);
}
TEST_F(RevenLogSourceTest, FetchDmiInfoWithValues) {
auto info = healthd::TelemetryInfo::New();
auto os_info = CreateOsInfo(healthd::BootMode::kUnknown);
auto dmi_info = CreateDmiInfo();
SetSystemInfo(info, std::move(os_info), std::move(dmi_info));
ash::cros_healthd::FakeCrosHealthd::Get()
->SetProbeTelemetryInfoResponseForTesting(info);
const std::unique_ptr<SystemLogsResponse> response = Fetch();
VerifyOutputContains(response, kRevenProductVendorKey, "LENOVO");
VerifyOutputContains(response, kRevenProductNameKey, "20U9001PUS");
VerifyOutputContains(response, kRevenProductVersionKey,
"ThinkPad X1 Carbon Gen 8");
VerifyOutputContains(response, kRevenBiosVersionKey, "N2WET26W (1.16 )");
}
TEST_F(RevenLogSourceTest, FetchDmiInfoWithoutValues) {
auto info = healthd::TelemetryInfo::New();
auto os_info = CreateOsInfo(healthd::BootMode::kCrosEfi);
auto dmi_info = healthd::DmiInfo::New();
SetSystemInfo(info, std::move(os_info), std::move(dmi_info));
ash::cros_healthd::FakeCrosHealthd::Get()
->SetProbeTelemetryInfoResponseForTesting(info);
const std::unique_ptr<SystemLogsResponse> response = Fetch();
const std::string not_available = "<not available>";
VerifyOutputContains(response, kRevenProductVendorKey, not_available);
VerifyOutputContains(response, kRevenProductNameKey, not_available);
VerifyOutputContains(response, kRevenProductVersionKey, not_available);
VerifyOutputContains(response, kRevenBiosVersionKey, not_available);
}
// BootMode::kCrosEfi: boot with EFI but not with secure boot.
TEST_F(RevenLogSourceTest, BiosBootMode_Uefi_True_SecureBoot_False) {
SetBootModeInfo(healthd::BootMode::kCrosEfi);
const std::unique_ptr<SystemLogsResponse> response = Fetch();
VerifyOutputContains(response, kRevenSecurebootKey, "false");
VerifyOutputContains(response, kRevenUefiKey, "true");
}
// BootMode::kCrosEfiSecure: boot with EFI security boot.
TEST_F(RevenLogSourceTest, BiosBootMode_Uefi_True_SecureBoot_True) {
SetBootModeInfo(healthd::BootMode::kCrosEfiSecure);
const std::unique_ptr<SystemLogsResponse> response = Fetch();
VerifyOutputContains(response, kRevenSecurebootKey, "true");
VerifyOutputContains(response, kRevenUefiKey, "true");
}
// BootMode::kCrosSecure: Chromebook/box firmware.
TEST_F(RevenLogSourceTest, BiosBootMode_CrosSecure) {
SetBootModeInfo(healthd::BootMode::kCrosSecure);
const std::unique_ptr<SystemLogsResponse> response = Fetch();
VerifyOutputContains(response, kRevenSecurebootKey, "false");
VerifyOutputContains(response, kRevenUefiKey, "false");
}
// BootMode::kCrosLegacy: Old BIOS firmware, or UEFI in "compatibility mode".
TEST_F(RevenLogSourceTest, BiosBootMode_CrosLegacy) {
SetBootModeInfo(healthd::BootMode::kCrosLegacy);
const std::unique_ptr<SystemLogsResponse> response = Fetch();
VerifyOutputContains(response, kRevenSecurebootKey, "false");
VerifyOutputContains(response, kRevenUefiKey, "false");
}
// BootMode::kUnknown: An issue with detection.
TEST_F(RevenLogSourceTest, BiosBootMode_Unknown) {
SetBootModeInfo(healthd::BootMode::kUnknown);
const std::unique_ptr<SystemLogsResponse> response = Fetch();
VerifyOutputContains(response, kRevenSecurebootKey, "false");
VerifyOutputContains(response, kRevenUefiKey, "false");
}
TEST_F(RevenLogSourceTest, PciEthernetDevices) {
auto info = healthd::TelemetryInfo::New();
SetPciEthernetDevices(info);
ash::cros_healthd::FakeCrosHealthd::Get()
->SetProbeTelemetryInfoResponseForTesting(info);
const std::unique_ptr<SystemLogsResponse> response = Fetch();
VerifyOutputContains(response, kRevenEthernetNameKey, "intel product1");
VerifyOutputContains(response, kRevenEthernetNameKey, "broadcom product2");
VerifyOutputContains(response, kRevenEthernetIdKey, "pci:12ab:34cd");
VerifyOutputContains(response, kRevenEthernetIdKey, "pci:56ab:78cd");
VerifyOutputContains(response, kRevenEthernetDriverKey, "driver1");
}
TEST_F(RevenLogSourceTest, PciBluetoothDevices) {
auto info = healthd::TelemetryInfo::New();
SetPciBluetoothDevices(info);
ash::cros_healthd::FakeCrosHealthd::Get()
->SetProbeTelemetryInfoResponseForTesting(info);
const std::unique_ptr<SystemLogsResponse> response = Fetch();
VerifyOutputContains(response, kRevenBluetoothNameKey,
"intel bluetooth_product1");
VerifyOutputContains(response, kRevenBluetoothNameKey,
"broadcom bluetooth_product2");
VerifyOutputContains(response, kRevenBluetoothIdKey, "pci:12ab:34cd");
VerifyOutputContains(response, kRevenBluetoothIdKey, "pci:56ab:78cd");
VerifyOutputContains(response, kRevenBluetoothDriverKey, "bluetooth_driver1");
}
TEST_F(RevenLogSourceTest, PciWirelessDevices) {
auto info = healthd::TelemetryInfo::New();
SetPciWirelessDevices(info);
ash::cros_healthd::FakeCrosHealthd::Get()
->SetProbeTelemetryInfoResponseForTesting(info);
const std::unique_ptr<SystemLogsResponse> response = Fetch();
VerifyOutputContains(response, kRevenWirelessNameKey,
"intel wireless_product1");
VerifyOutputContains(response, kRevenWirelessNameKey,
"broadcom wireless_product2");
VerifyOutputContains(response, kRevenWirelessIdKey, "pci:12ab:34cd");
VerifyOutputContains(response, kRevenWirelessIdKey, "pci:56ab:78cd");
VerifyOutputContains(response, kRevenWirelessDriverKey, "wireless_driver1");
}
TEST_F(RevenLogSourceTest, PciGpuInfo) {
auto info = healthd::TelemetryInfo::New();
SetPciDisplayDevices(info);
ash::cros_healthd::FakeCrosHealthd::Get()
->SetProbeTelemetryInfoResponseForTesting(info);
const std::unique_ptr<SystemLogsResponse> response = Fetch();
VerifyOutputContains(response, kRevenGpuNameKey, "intel 945GM");
VerifyOutputContains(response, kRevenGpuIdKey, "pci:12ab:34cd");
VerifyOutputContains(response, kRevenGpuDriverKey, "driver1");
}
TEST_F(RevenLogSourceTest, UsbEthernetDevices) {
auto info = healthd::TelemetryInfo::New();
SetUsbEthernetDevices(info);
ash::cros_healthd::FakeCrosHealthd::Get()
->SetProbeTelemetryInfoResponseForTesting(info);
const std::unique_ptr<SystemLogsResponse> response = Fetch();
VerifyOutputContains(response, kRevenEthernetNameKey, "intel product1");
VerifyOutputContains(response, kRevenEthernetNameKey, "broadcom product2");
VerifyOutputContains(response, kRevenEthernetIdKey, "usb:12ab:34cd");
VerifyOutputContains(response, kRevenEthernetIdKey, "usb:56ab:78cd");
VerifyOutputContains(response, kRevenEthernetDriverKey, "driver1");
}
TEST_F(RevenLogSourceTest, UsbBluetoothDevices) {
auto info = healthd::TelemetryInfo::New();
SetUsbBluetoothDevices(info);
ash::cros_healthd::FakeCrosHealthd::Get()
->SetProbeTelemetryInfoResponseForTesting(info);
const std::unique_ptr<SystemLogsResponse> response = Fetch();
VerifyOutputContains(response, kRevenBluetoothNameKey,
"intel bluetooth_product1");
VerifyOutputContains(response, kRevenBluetoothNameKey,
"broadcom bluetooth_product2");
VerifyOutputContains(response, kRevenBluetoothIdKey, "usb:12ab:34cd");
VerifyOutputContains(response, kRevenBluetoothIdKey, "usb:56ab:78cd");
VerifyOutputContains(response, kRevenBluetoothDriverKey, "bluetooth_driver1");
}
TEST_F(RevenLogSourceTest, UsbWirelessDevices) {
auto info = healthd::TelemetryInfo::New();
SetUsbWirelessDevices(info);
ash::cros_healthd::FakeCrosHealthd::Get()
->SetProbeTelemetryInfoResponseForTesting(info);
const std::unique_ptr<SystemLogsResponse> response = Fetch();
VerifyOutputContains(response, kRevenWirelessNameKey,
"intel wireless_product1");
VerifyOutputContains(response, kRevenWirelessNameKey,
"broadcom wireless_product2");
VerifyOutputContains(response, kRevenWirelessIdKey, "usb:12ab:34cd");
VerifyOutputContains(response, kRevenWirelessIdKey, "usb:56ab:78cd");
VerifyOutputContains(response, kRevenWirelessDriverKey, "wireless_driver1");
}
TEST_F(RevenLogSourceTest, UsbGpuInfo) {
auto info = healthd::TelemetryInfo::New();
SetUsbDisplayDevices(info);
ash::cros_healthd::FakeCrosHealthd::Get()
->SetProbeTelemetryInfoResponseForTesting(info);
const std::unique_ptr<SystemLogsResponse> response = Fetch();
VerifyOutputContains(response, kRevenGpuNameKey, "intel product1");
VerifyOutputContains(response, kRevenGpuIdKey, "usb:12ab:34cd");
VerifyOutputContains(response, kRevenGpuDriverKey, "driver1");
}
TEST_F(RevenLogSourceTest, TpmInfoVersion_1_2WithDidVid_Owned_Allowed) {
const uint32_t version = 0x312e3200; // TPM 1.2
const std::string did_vid = "286536196";
const bool is_owned = true;
const bool is_allowed = true;
auto info = healthd::TelemetryInfo::New();
SetTpmInfo(info, did_vid, version, is_owned, is_allowed);
ash::cros_healthd::FakeCrosHealthd::Get()
->SetProbeTelemetryInfoResponseForTesting(info);
const std::unique_ptr<SystemLogsResponse> response = Fetch();
VerifyOutputContains(response, kRevenTpmVersionKey, "1.2");
VerifyOutputContains(response, kRevenTpmSpecLevelKey, "116");
VerifyOutputContains(response, kRevenTpmManufacturerKey, "1129467731");
VerifyOutputContains(response, kRevenTpmDidVidKey, "286536196");
VerifyOutputContains(response, kRevenTpmOwnedKey, "true");
VerifyOutputContains(response, kRevenTpmAllowListedKey, "true");
}
TEST_F(RevenLogSourceTest, TpmInfoVersion_2_0WithoutDidVid_Owned_NotAllowed) {
const uint32_t version = 0x322e3000; // TPM 2.0
const std::string did_vid = "";
const bool is_owned = true;
const bool is_allowed = false;
auto info = healthd::TelemetryInfo::New();
SetTpmInfo(info, did_vid, version, is_owned, is_allowed);
ash::cros_healthd::FakeCrosHealthd::Get()
->SetProbeTelemetryInfoResponseForTesting(info);
const std::unique_ptr<SystemLogsResponse> response = Fetch();
VerifyOutputContains(response, kRevenTpmVersionKey, "2.0");
VerifyOutputContains(response, kRevenTpmSpecLevelKey, "116");
VerifyOutputContains(response, kRevenTpmManufacturerKey, "1129467731");
VerifyOutputContains(response, kRevenTpmDidVidKey, "");
VerifyOutputContains(response, kRevenTpmOwnedKey, "true");
VerifyOutputContains(response, kRevenTpmAllowListedKey, "false");
}
TEST_F(RevenLogSourceTest,
TpmInfoVersionUnknownWithoutDidVid_Allowed_NotOwned) {
const uint32_t version = 0xaaaaaaaa;
const std::string did_vid = "";
const bool is_owned = false;
const bool is_allowed = true;
auto info = healthd::TelemetryInfo::New();
SetTpmInfo(info, did_vid, version, is_owned, is_allowed);
ash::cros_healthd::FakeCrosHealthd::Get()
->SetProbeTelemetryInfoResponseForTesting(info);
const std::unique_ptr<SystemLogsResponse> response = Fetch();
VerifyOutputContains(response, kRevenTpmVersionKey, "unknown");
VerifyOutputContains(response, kRevenTpmSpecLevelKey, "116");
VerifyOutputContains(response, kRevenTpmManufacturerKey, "1129467731");
VerifyOutputContains(response, kRevenTpmDidVidKey, "");
VerifyOutputContains(response, kRevenTpmOwnedKey, "false");
VerifyOutputContains(response, kRevenTpmAllowListedKey, "true");
}
TEST_F(RevenLogSourceTest,
TpmInfoVersionUnknownWithoutDidVid_NotAllowed_NotOwned) {
const uint32_t version = 0xaaaaaaaa;
const std::string did_vid = "";
const bool is_owned = false;
const bool is_allowed = false;
auto info = healthd::TelemetryInfo::New();
SetTpmInfo(info, did_vid, version, is_owned, is_allowed);
ash::cros_healthd::FakeCrosHealthd::Get()
->SetProbeTelemetryInfoResponseForTesting(info);
const std::unique_ptr<SystemLogsResponse> response = Fetch();
VerifyOutputContains(response, kRevenTpmVersionKey, "unknown");
VerifyOutputContains(response, kRevenTpmSpecLevelKey, "116");
VerifyOutputContains(response, kRevenTpmManufacturerKey, "1129467731");
VerifyOutputContains(response, kRevenTpmDidVidKey, "");
VerifyOutputContains(response, kRevenTpmOwnedKey, "false");
VerifyOutputContains(response, kRevenTpmAllowListedKey, "false");
}
TEST_F(RevenLogSourceTest, GraphicsInfoNoExtensions) {
auto info = healthd::TelemetryInfo::New();
std::vector<std::string> extensions;
SetGraphicsInfo(info, extensions);
ash::cros_healthd::FakeCrosHealthd::Get()
->SetProbeTelemetryInfoResponseForTesting(info);
const std::unique_ptr<SystemLogsResponse> response = Fetch();
VerifyOutputContains(response, kRevenGlVersionKey, "fake_version");
VerifyOutputContains(response, kRevenGlShadingVersionKey,
"fake_shading_version");
VerifyOutputContains(response, kRevenGlVendorKey, "fake_vendor");
VerifyOutputContains(response, kRevenGlRendererKey, "fake_renderer");
VerifyOutputContains(response, kRevenGlExtensionsKey, "");
}
TEST_F(RevenLogSourceTest, GraphicsInfoOneExtension) {
auto info = healthd::TelemetryInfo::New();
std::vector<std::string> extensions{"ext1"};
SetGraphicsInfo(info, extensions);
ash::cros_healthd::FakeCrosHealthd::Get()
->SetProbeTelemetryInfoResponseForTesting(info);
const std::unique_ptr<SystemLogsResponse> response = Fetch();
VerifyOutputContains(response, kRevenGlVersionKey, "fake_version");
VerifyOutputContains(response, kRevenGlShadingVersionKey,
"fake_shading_version");
VerifyOutputContains(response, kRevenGlVendorKey, "fake_vendor");
VerifyOutputContains(response, kRevenGlRendererKey, "fake_renderer");
VerifyOutputContains(response, kRevenGlExtensionsKey, "ext1");
}
TEST_F(RevenLogSourceTest, GraphicsInfoTwoExtensions) {
auto info = healthd::TelemetryInfo::New();
std::vector<std::string> extensions{"ext1", "ext2"};
SetGraphicsInfo(info, extensions);
ash::cros_healthd::FakeCrosHealthd::Get()
->SetProbeTelemetryInfoResponseForTesting(info);
const std::unique_ptr<SystemLogsResponse> response = Fetch();
VerifyOutputContains(response, kRevenGlVersionKey, "fake_version");
VerifyOutputContains(response, kRevenGlShadingVersionKey,
"fake_shading_version");
VerifyOutputContains(response, kRevenGlVendorKey, "fake_vendor");
VerifyOutputContains(response, kRevenGlRendererKey, "fake_renderer");
VerifyOutputContains(response, kRevenGlExtensionsKey, "ext1, ext2");
}
TEST_F(RevenLogSourceTest, TouchpadStack) {
auto info = healthd::TelemetryInfo::New();
ash::cros_healthd::FakeCrosHealthd::Get()
->SetProbeTelemetryInfoResponseForTesting(info);
const std::unique_ptr<SystemLogsResponse> response = Fetch();
ASSERT_NE(response, nullptr);
const auto response_iter = response->find(kRevenTouchpadStack);
ASSERT_NE(response_iter, response->end());
EXPECT_THAT(response_iter->second,
AnyOf(HasSubstr("libinput"), HasSubstr("gestures"),
HasSubstr("Default EventConverterEvdev")));
}
TEST_F(RevenLogSourceTest, NothingAvailable) {
auto info = healthd::TelemetryInfo::New();
const std::unique_ptr<SystemLogsResponse> response = Fetch();
const std::string not_available = "<not available>";
VerifyOutputContains(response, kRevenProductVendorKey, not_available);
VerifyOutputContains(response, kRevenProductNameKey, not_available);
VerifyOutputContains(response, kRevenProductVersionKey, not_available);
VerifyOutputContains(response, kRevenBiosVersionKey, not_available);
VerifyOutputContains(response, kRevenEthernetNameKey, not_available);
VerifyOutputContains(response, kRevenEthernetIdKey, not_available);
VerifyOutputContains(response, kRevenEthernetDriverKey, not_available);
VerifyOutputContains(response, kRevenWirelessNameKey, not_available);
VerifyOutputContains(response, kRevenWirelessIdKey, not_available);
VerifyOutputContains(response, kRevenWirelessDriverKey, not_available);
VerifyOutputContains(response, kRevenBluetoothNameKey, not_available);
VerifyOutputContains(response, kRevenBluetoothIdKey, not_available);
VerifyOutputContains(response, kRevenBluetoothDriverKey, not_available);
VerifyOutputContains(response, kRevenGpuNameKey, not_available);
VerifyOutputContains(response, kRevenGpuIdKey, not_available);
VerifyOutputContains(response, kRevenGpuDriverKey, not_available);
VerifyOutputContains(response, kRevenCpuNameKey, not_available);
VerifyOutputContains(response, kRevenTotalMemoryKey, not_available);
VerifyOutputContains(response, kRevenFreeMemoryKey, not_available);
VerifyOutputContains(response, kRevenAvailableMemoryKey, not_available);
VerifyOutputContains(response, kRevenSecurebootKey, not_available);
VerifyOutputContains(response, kRevenUefiKey, not_available);
VerifyOutputContains(response, kRevenTpmVersionKey, not_available);
VerifyOutputContains(response, kRevenTpmSpecLevelKey, not_available);
VerifyOutputContains(response, kRevenTpmManufacturerKey, not_available);
VerifyOutputContains(response, kRevenTpmDidVidKey, not_available);
VerifyOutputContains(response, kRevenTpmAllowListedKey, not_available);
VerifyOutputContains(response, kRevenTpmOwnedKey, not_available);
VerifyOutputContains(response, kRevenGlVersionKey, not_available);
VerifyOutputContains(response, kRevenGlShadingVersionKey, not_available);
VerifyOutputContains(response, kRevenGlVendorKey, not_available);
VerifyOutputContains(response, kRevenGlRendererKey, not_available);
VerifyOutputContains(response, kRevenGlExtensionsKey, not_available);
// Touchpad stack is always set to something.
VerifyOutputContains(response, kRevenTouchpadStack, "");
// To remind folks to add all new keys here, also check total number of keys.
uint16_t expected_num_keys = 34;
EXPECT_THAT(response->size(), expected_num_keys);
}
} // namespace system_logs