From cec3306c229aa8dd84c12eb6b5994f4ae0e9f4fe Mon Sep 17 00:00:00 2001 From: Justin Kim Date: Mon, 18 Nov 2024 11:31:58 -0800 Subject: [PATCH] Cross validate Sensors against PM config validator Summary: Extract sensor name and validate the symlink against PM config validator. With that, we fixed Montblanc sensor service config. Next step: 1. Request CLS to change regarding naming issues -- E.g. SMB_TSENSOR* in MCB unit. 2. Validate correct PmUnitName is defined for the SlotPath. Reviewed By: somasun Differential Revision: D65923827 fbshipit-source-id: 21a2f06e61565b4427c4975b3f50a58fe6d4ecc2 --- .../configs/montblanc/sensor_service.json | 120 ++++++++-------- .../platform_manager/ConfigValidator.h | 2 +- fboss/platform/sensor_service/BUCK | 1 + .../sensor_service/ConfigValidator.cpp | 131 ++++++++++++----- .../platform/sensor_service/ConfigValidator.h | 18 ++- .../test/ConfigValidatorTest.cpp | 134 ++++++++++++------ 6 files changed, 259 insertions(+), 147 deletions(-) diff --git a/fboss/platform/configs/montblanc/sensor_service.json b/fboss/platform/configs/montblanc/sensor_service.json index 90edbb3be68a4..c419aa1b2dc84 100644 --- a/fboss/platform/configs/montblanc/sensor_service.json +++ b/fboss/platform/configs/montblanc/sensor_service.json @@ -4,6 +4,46 @@ "slotPath": "/", "pmUnitName": "MINIPACK3_MCB", "sensors": [ + { + "name": "SMB_LEFT_U51_TEMP", + "sysfsPath": "/run/devmap/sensors/SMB_TSENSOR5/temp1_input", + "type": 3, + "thresholds": { + "upperCriticalVal": 85, + "maxAlarmVal": 80 + }, + "compute": "@/1000" + }, + { + "name": "SMB_OUTLET_U57_TEMP", + "sysfsPath": "/run/devmap/sensors/SMB_TSENSOR2/temp1_input", + "type": 3, + "thresholds": { + "upperCriticalVal": 95, + "maxAlarmVal": 90 + }, + "compute": "@/1000" + }, + { + "name": "SMB_BEHIND_TH5_U39_TEMP", + "sysfsPath": "/run/devmap/sensors/SMB_TSENSOR3/temp1_input", + "type": 3, + "thresholds": { + "upperCriticalVal": 95, + "maxAlarmVal": 90 + }, + "compute": "@/1000" + }, + { + "name": "SMB_RIGHT_U182_TEMP", + "sysfsPath": "/run/devmap/sensors/SMB_TSENSOR6/temp1_input", + "type": 3, + "thresholds": { + "upperCriticalVal": 85, + "maxAlarmVal": 80 + }, + "compute": "@/1000" + }, { "name": "CPU_UNCORE_TEMP", "sysfsPath": "/run/devmap/sensors/CPU_CORE_TEMP/temp1_input", @@ -598,26 +638,6 @@ "slotPath": "/SCM_SLOT@0/COMESE_SLOT@0", "pmUnitName": "NETLAKE", "sensors": [ - { - "name": "COME_U18_INLET_SENSOR_TMP75_TEMP", - "sysfsPath": "/run/devmap/sensors/COME_TSENSOR1/temp1_input", - "type": 3, - "thresholds": { - "maxAlarmVal": 60, - "upperCriticalVal": 65 - }, - "compute": "@/1000" - }, - { - "name": "COME_U39_OUTLET_SENSOR_TMP75_TEMP", - "sysfsPath": "/run/devmap/sensors/COME_TSENSOR2/temp1_input", - "type": 3, - "thresholds": { - "maxAlarmVal": 60, - "upperCriticalVal": 65 - }, - "compute": "@/1000" - }, { "name": "COME_PU31_TDA38640_PVNN_PCH_VIN", "sysfsPath": "/run/devmap/sensors/COME_VOLTAGE_MONITOR1/in1_input", @@ -1388,6 +1408,26 @@ "slotPath": "/SCM_SLOT@0", "pmUnitName": "MINIPACK3_SCM", "sensors": [ + { + "name": "COME_U18_INLET_SENSOR_TMP75_TEMP", + "sysfsPath": "/run/devmap/sensors/COME_TSENSOR1/temp1_input", + "type": 3, + "thresholds": { + "maxAlarmVal": 60, + "upperCriticalVal": 65 + }, + "compute": "@/1000" + }, + { + "name": "COME_U39_OUTLET_SENSOR_TMP75_TEMP", + "sysfsPath": "/run/devmap/sensors/COME_TSENSOR2/temp1_input", + "type": 3, + "thresholds": { + "maxAlarmVal": 60, + "upperCriticalVal": 65 + }, + "compute": "@/1000" + }, { "name": "SCM_M2_SSD_TEMP", "sysfsPath": "/run/devmap/sensors/SCM_M2_SSD_TEMP/temp1_input", @@ -1669,46 +1709,6 @@ "slotPath": "/SMB_SLOT@0", "pmUnitName": "MINIPACK3_SMB", "sensors": [ - { - "name": "SMB_LEFT_U51_TEMP", - "sysfsPath": "/run/devmap/sensors/SMB_TSENSOR5/temp1_input", - "type": 3, - "thresholds": { - "upperCriticalVal": 85, - "maxAlarmVal": 80 - }, - "compute": "@/1000" - }, - { - "name": "SMB_OUTLET_U57_TEMP", - "sysfsPath": "/run/devmap/sensors/SMB_TSENSOR2/temp1_input", - "type": 3, - "thresholds": { - "upperCriticalVal": 95, - "maxAlarmVal": 90 - }, - "compute": "@/1000" - }, - { - "name": "SMB_BEHIND_TH5_U39_TEMP", - "sysfsPath": "/run/devmap/sensors/SMB_TSENSOR3/temp1_input", - "type": 3, - "thresholds": { - "upperCriticalVal": 95, - "maxAlarmVal": 90 - }, - "compute": "@/1000" - }, - { - "name": "SMB_RIGHT_U182_TEMP", - "sysfsPath": "/run/devmap/sensors/SMB_TSENSOR6/temp1_input", - "type": 3, - "thresholds": { - "upperCriticalVal": 85, - "maxAlarmVal": 80 - }, - "compute": "@/1000" - }, { "name": "SMB_XP3R3V_CLK", "sysfsPath": "/run/devmap/sensors/SMB_VOLTAGE_MONITOR1/in0_input", diff --git a/fboss/platform/platform_manager/ConfigValidator.h b/fboss/platform/platform_manager/ConfigValidator.h index 233d25c360483..7a53fe56ad2ae 100644 --- a/fboss/platform/platform_manager/ConfigValidator.h +++ b/fboss/platform/platform_manager/ConfigValidator.h @@ -24,7 +24,7 @@ class ConfigValidator { virtual bool isValidSlotPath( const PlatformConfig& platformConfig, const std::string& slotPath); - bool isValidDeviceName( + virtual bool isValidDeviceName( const PlatformConfig& platformConfig, const std::string& slotPath, const std::string& deviceName); diff --git a/fboss/platform/sensor_service/BUCK b/fboss/platform/sensor_service/BUCK index 6c8fd18c81cdc..aaadf361236f8 100644 --- a/fboss/platform/sensor_service/BUCK +++ b/fboss/platform/sensor_service/BUCK @@ -104,6 +104,7 @@ cpp_library( exported_deps = [ "fbsource//third-party/fmt:fmt", "//fboss/platform/platform_manager:config_validator", + "//fboss/platform/platform_manager:utils", "//fboss/platform/sensor_service/if:sensor_config-cpp2-types", "//folly/logging:logging", ], diff --git a/fboss/platform/sensor_service/ConfigValidator.cpp b/fboss/platform/sensor_service/ConfigValidator.cpp index 67d77b861d992..d1c9a2d20eeec 100644 --- a/fboss/platform/sensor_service/ConfigValidator.cpp +++ b/fboss/platform/sensor_service/ConfigValidator.cpp @@ -6,8 +6,13 @@ #include #include +#include "fboss/platform/platform_manager/Utils.h" + namespace facebook::fboss::platform::sensor_service { using namespace sensor_config; +namespace { +const re2::RE2 kSensorSymlinkRegex{"(?P/run/devmap/sensors/.+)(/.+)+"}; +}; // namespace ConfigValidator::ConfigValidator( const std::shared_ptr& pmConfigValidator) @@ -16,11 +21,8 @@ ConfigValidator::ConfigValidator( bool ConfigValidator::isValid( const SensorConfig& sensorConfig, const std::optional& platformConfig) { - for (std::unordered_set> usedSlotPaths; - const auto& pmUnitSensors : *sensorConfig.pmUnitSensorsList()) { - if (!isValidPmUnitSensors(pmUnitSensors, usedSlotPaths)) { - return false; - } + if (!isValidPmUnitSensorsList(*sensorConfig.pmUnitSensorsList())) { + return false; } // This is Darwin if platformConfig=std::nullopt // Until it onboards PM, we can't cross-validate against PM. @@ -28,52 +30,105 @@ bool ConfigValidator::isValid( return true; } // Cross-validation agains platform_manager::ConfigValidator. - for (const auto& pmUnitSensors : *sensorConfig.pmUnitSensorsList()) { - if (!pmConfigValidator_->isValidSlotPath( - *platformConfig, *pmUnitSensors.slotPath())) { + if (!isPmValidPmUnitSensorList( + *platformConfig, *sensorConfig.pmUnitSensorsList())) { + return false; + } + return true; +} + +bool ConfigValidator::isValidPmUnitSensorsList( + const std::vector& pmUnitSensorsList) { + std::unordered_set> usedSlotPaths; + for (const auto& pmUnitSensors : pmUnitSensorsList) { + if (usedSlotPaths.contains( + {*pmUnitSensors.slotPath(), *pmUnitSensors.pmUnitName()})) { + XLOG(ERR) << fmt::format( + "(SlotPath {}, PmUnitName {}) is a duplicate", + *pmUnitSensors.slotPath(), + *pmUnitSensors.pmUnitName()); + return false; + } + usedSlotPaths.insert( + {*pmUnitSensors.slotPath(), *pmUnitSensors.pmUnitName()}); + if (!isValidPmSensors(*pmUnitSensors.sensors())) { return false; } } return true; } -bool ConfigValidator::isValidPmUnitSensors( - const PmUnitSensors& pmUnitSensors, - std::unordered_set>& usedSlotPaths) { - if (usedSlotPaths.contains( - {*pmUnitSensors.slotPath(), *pmUnitSensors.pmUnitName()})) { - XLOG(ERR) << fmt::format( - "(SlotPath {}, PmUnitName {}) is a duplicate", - *pmUnitSensors.slotPath(), - *pmUnitSensors.pmUnitName()); - return false; - } - usedSlotPaths.insert( - {*pmUnitSensors.slotPath(), *pmUnitSensors.pmUnitName()}); - for (std::unordered_set usedSensorNames; - const auto& pmSensor : *pmUnitSensors.sensors()) { - if (!isValidPmSensor(pmSensor, usedSensorNames)) { +bool ConfigValidator::isValidPmSensors(const std::vector& pmSensors) { + std::unordered_set usedSensorNames; + for (const auto& pmSensor : pmSensors) { + if (pmSensor.name()->empty()) { + XLOG(ERR) << "PmSensor name must be non-empty"; + return false; + } + if (usedSensorNames.contains(*pmSensor.name())) { + XLOG(ERR) << fmt::format( + "SensorName {} is a duplicate", *pmSensor.name()); + return false; + } + usedSensorNames.emplace(*pmSensor.name()); + if (!pmSensor.sysfsPath()->starts_with("/run/devmap/sensors/")) { + XLOG(ERR) << "PmSensor sysfsPath must start with /run/devmap/sensors/"; return false; } } return true; } -bool ConfigValidator::isValidPmSensor( - const PmSensor& pmSensor, - std::unordered_set& usedSensorNames) { - if (pmSensor.name()->empty()) { - XLOG(ERR) << "PmSensor name must be non-empty"; - return false; - } - if (usedSensorNames.contains(*pmSensor.name())) { - XLOG(ERR) << fmt::format("SensorName {} is a duplicate", *pmSensor.name()); - return false; +bool ConfigValidator::isPmValidPmUnitSensorList( + const platform_manager::PlatformConfig& platformConfig, + const std::vector& pmUnitSensorsList) { + for (const auto& pmUnitSensors : pmUnitSensorsList) { + if (!pmConfigValidator_->isValidSlotPath( + platformConfig, *pmUnitSensors.slotPath())) { + return false; + } + if (!isPmValidPmSensors( + platformConfig, + *pmUnitSensors.slotPath(), + *pmUnitSensors.sensors())) { + return false; + } } - usedSensorNames.emplace(*pmSensor.name()); - if (!pmSensor.sysfsPath()->starts_with("/run/devmap/sensors/")) { - XLOG(ERR) << "PmSensor sysfsPath must start with /run/devmap/sensors/"; - return false; + return true; +} + +bool ConfigValidator::isPmValidPmSensors( + const platform_manager::PlatformConfig& platformConfig, + const std::string& pmUnitSensorsSlotPath, + const std::vector& pmSensors) { + for (const auto& pmSensor : pmSensors) { + std::string symlink; + if (!re2::RE2::FullMatch( + *pmSensor.sysfsPath(), kSensorSymlinkRegex, &symlink)) { + XLOG(ERR) << fmt::format( + "Fail to extract sensor symlink from {}", *pmSensor.sysfsPath()); + return false; + } + if (!platformConfig.symbolicLinkToDevicePath()->contains(symlink)) { + XLOG(ERR) << fmt::format( + "{} is not defined in PlatformConfig::symbolicLinkToDevicePath", + symlink); + return false; + } + auto [slotPath, deviceName] = platform_manager::Utils().parseDevicePath( + platformConfig.symbolicLinkToDevicePath()->at(symlink)); + if (pmUnitSensorsSlotPath != slotPath) { + XLOG(ERR) << fmt::format( + "PmUnitSensors SlotPath {} doesn't match with SlotPath {} of {}", + pmUnitSensorsSlotPath, + slotPath, + symlink); + return false; + } + if (!pmConfigValidator_->isValidDeviceName( + platformConfig, pmUnitSensorsSlotPath, deviceName)) { + return false; + } } return true; } diff --git a/fboss/platform/sensor_service/ConfigValidator.h b/fboss/platform/sensor_service/ConfigValidator.h index b7bb1b8ada8cb..d72a212da1294 100644 --- a/fboss/platform/sensor_service/ConfigValidator.h +++ b/fboss/platform/sensor_service/ConfigValidator.h @@ -15,13 +15,19 @@ class ConfigValidator { bool isValid( const sensor_config::SensorConfig& sensorConfig, const std::optional& platformConfig); - bool isValidPmUnitSensors( - const sensor_config::PmUnitSensors& PmUnitSensors, - std::unordered_set>& usedSlotPaths); - bool isValidPmSensor( - const sensor_config::PmSensor& pmSensor, - std::unordered_set& usedSensorNames); + // Local validation + bool isValidPmUnitSensorsList( + const std::vector& pmUnitSensorsList); + bool isValidPmSensors(const std::vector& pmSensor); bool isValidSlotPath(const std::string& slotPath); + // PlatformManager validation + bool isPmValidPmUnitSensorList( + const platform_manager::PlatformConfig& platformConfig, + const std::vector& pmUnitSensorsList); + bool isPmValidPmSensors( + const platform_manager::PlatformConfig& platformConfig, + const std::string& pmUnitSensorsSlotPath, + const std::vector& pmSensors); private: const std::shared_ptr pmConfigValidator_; diff --git a/fboss/platform/sensor_service/test/ConfigValidatorTest.cpp b/fboss/platform/sensor_service/test/ConfigValidatorTest.cpp index 61461d4dd58e0..1191fda68c6f2 100644 --- a/fboss/platform/sensor_service/test/ConfigValidatorTest.cpp +++ b/fboss/platform/sensor_service/test/ConfigValidatorTest.cpp @@ -24,6 +24,12 @@ class MockPmConfigValidator : public platform_manager::ConfigValidator { bool, isValidSlotPath, (const platform_manager::PlatformConfig&, const std::string&)); + MOCK_METHOD( + bool, + isValidDeviceName, + (const platform_manager::PlatformConfig&, + const std::string&, + const std::string&)); }; class ConfigValidatorTest : public testing::Test { @@ -37,82 +43,126 @@ class ConfigValidatorTest : public testing::Test { }; TEST_F(ConfigValidatorTest, ValidConfig) { - EXPECT_CALL(*mockPmConfigValidator_, isValidSlotPath(_, _)) - .Times(2 /* # of PmUnitSensors*/) - .WillRepeatedly(Return(true)); auto config = SensorConfig(); PmUnitSensors pmUnitSensors1, pmUnitSensors2; pmUnitSensors1.slotPath() = "/"; pmUnitSensors1.sensors() = { - createPmSensor("sensor1", "/run/devmap/sensors/CPU_CORE_TEMP")}; + createPmSensor("sensor1", "/run/devmap/sensors/CPU_CORE_TEMP/input1")}; pmUnitSensors2.slotPath() = "/BCB_SLOT@0"; - pmUnitSensors1.sensors() = { - createPmSensor("sensor2", "/run/devmap/sensors/BCB_FAN_CPLD")}; + pmUnitSensors2.sensors() = { + createPmSensor("sensor2", "/run/devmap/sensors/BCB_FAN_CPLD/pwm3")}; config.pmUnitSensorsList() = {pmUnitSensors1, pmUnitSensors2}; + platformConfig_.symbolicLinkToDevicePath() = { + {"/run/devmap/sensors/CPU_CORE_TEMP", "/[CPU_CORE_TEMP]"}, + {"/run/devmap/sensors/BCB_FAN_CPLD", "/BCB_SLOT@0/[BCB_FAN_CPLD]"}}; + EXPECT_CALL(*mockPmConfigValidator_, isValidSlotPath(_, _)) + .Times(2 /* # of PmUnitSensors*/) + .WillRepeatedly(Return(true)); + EXPECT_CALL(*mockPmConfigValidator_, isValidDeviceName(_, _, _)) + .Times(2 /* # of PmUnitSensors*/) + .WillRepeatedly(Return(true)); EXPECT_TRUE(configValidator_.isValid(config, platformConfig_)); } - TEST_F(ConfigValidatorTest, ValidConfigForDarwin) { EXPECT_CALL(*mockPmConfigValidator_, isValidSlotPath(_, _)).Times(0); auto config = SensorConfig(); PmUnitSensors pmUnitSensors1, pmUnitSensors2; pmUnitSensors1.slotPath() = "/"; pmUnitSensors1.sensors() = { - createPmSensor("sensor1", "/run/devmap/sensors/CPU_CORE_TEMP")}; + createPmSensor("sensor1", "/run/devmap/sensors/CPU_CORE_TEMP/input1")}; pmUnitSensors2.slotPath() = "/BCB_SLOT@0"; - pmUnitSensors1.sensors() = { - createPmSensor("sensor2", "/run/devmap/sensors/BCB_FAN_CPLD")}; + pmUnitSensors2.sensors() = { + createPmSensor("sensor2", "/run/devmap/sensors/BCB_FAN_CPLD/pwm3")}; config.pmUnitSensorsList() = {pmUnitSensors1, pmUnitSensors2}; EXPECT_TRUE(configValidator_.isValid(config, std::nullopt)); } -TEST_F(ConfigValidatorTest, PmUnitSensors) { +TEST_F(ConfigValidatorTest, ValidPmUnitSensors) { SensorConfig config; PmUnitSensors pmUnitSensors1, pmUnitSensors2; pmUnitSensors1.slotPath() = "/BCB_SLOT@0"; pmUnitSensors1.pmUnitName() = "BCB"; + pmUnitSensors1.sensors() = {}; pmUnitSensors2.slotPath() = "/BCB_SLOT@0"; pmUnitSensors2.pmUnitName() = "BCB2"; - config.pmUnitSensorsList() = {pmUnitSensors1, pmUnitSensors2}; + pmUnitSensors2.sensors() = {}; // Valid PmUnitSensors + EXPECT_TRUE(configValidator_.isValidPmUnitSensorsList( + {pmUnitSensors1, pmUnitSensors2})); + // Invalid PmUnitSensors -- Duplicate (SlotPath, PmUnitName) Pairing + pmUnitSensors2.pmUnitName() = "BCB"; + EXPECT_FALSE(configValidator_.isValidPmUnitSensorsList( + {pmUnitSensors1, pmUnitSensors2})); +} + +TEST_F(ConfigValidatorTest, PmValidPmUnitSensors) { + SensorConfig config; + PmUnitSensors pmUnitSensors1, pmUnitSensors2; + pmUnitSensors1.slotPath() = "/BCB_SLOT@0"; + pmUnitSensors1.pmUnitName() = "BCB"; + pmUnitSensors1.sensors() = {}; + pmUnitSensors2.slotPath() = "/BCB_SLOT@0"; + pmUnitSensors2.pmUnitName() = "BCB2"; + pmUnitSensors2.sensors() = {}; + // PmValid PmUnitSensors EXPECT_CALL( *mockPmConfigValidator_, isValidSlotPath(platformConfig_, "/BCB_SLOT@0")) - .Times(2 /* # of PmUnitSensors */) + .Times(2) .WillRepeatedly(Return(true)); - EXPECT_TRUE(configValidator_.isValid(config, platformConfig_)); + EXPECT_TRUE(configValidator_.isPmValidPmUnitSensorList( + platformConfig_, {pmUnitSensors1, pmUnitSensors2})); // Invalid PmUnitSensors -- Invalid SlotPath EXPECT_CALL( *mockPmConfigValidator_, isValidSlotPath(platformConfig_, "/BCB_SLOT@0")) .WillOnce(Return(false)); - EXPECT_FALSE(configValidator_.isValid(config, platformConfig_)); - // Invalid PmUnitSensors -- Duplicate (SlotPath, PmUnitName) Pairing - EXPECT_CALL( - *mockPmConfigValidator_, isValidSlotPath(platformConfig_, "/BCB_SLOT@0")) - .Times(0); - pmUnitSensors2.pmUnitName() = "BCB"; - config.pmUnitSensorsList() = {pmUnitSensors1, pmUnitSensors2}; - EXPECT_FALSE(configValidator_.isValid(config, platformConfig_)); + EXPECT_FALSE(configValidator_.isPmValidPmUnitSensorList( + platformConfig_, {pmUnitSensors1, pmUnitSensors2})); } -TEST_F(ConfigValidatorTest, InvalidPmSensors) { - // At this point, only interested in PmSensors, suppose SlotPaths are valid. - EXPECT_CALL(*mockPmConfigValidator_, isValidSlotPath(_, _)) - .WillRepeatedly(Return(true)); +TEST_F(ConfigValidatorTest, ValidPmSensors) { + // Invalid PmSensor -- Empty sensor name + EXPECT_FALSE(configValidator_.isValidPmSensors( + {createPmSensor("", "/run/devmap/sensors/BCB_FAN_CPLD/pwm3")})); + // Invalid PmSensor -- Invalid sysfs path + EXPECT_FALSE(configValidator_.isValidPmSensors( + {createPmSensor("sensor1", "/run/devmap/eeproms/BCB_EEPROMS/xyz")})); + // Invalid PmSensor -- Duplicate sensor name + EXPECT_FALSE(configValidator_.isValidPmSensors( + {createPmSensor("sensor1", "/run/devmap/sensors/BCB_FAN_CPLD/pwm3"), + createPmSensor( + "sensor1", "/run/devmap/sensors/BCB_FAN_CPLD2/fan_input")})); + // Valid PmSensor + EXPECT_TRUE(configValidator_.isValidPmSensors( + {createPmSensor("sensor1", "/run/devmap/sensors/BCB_FAN_CPLD/pwm3"), + createPmSensor( + "sensor2", "/run/devmap/sensors/BCB_FAN_CPLD2/fan_input")})); +} - auto config = SensorConfig(); - PmUnitSensors pmUnitSensors; - pmUnitSensors.slotPath() = "/BCB_SLOT@0"; - pmUnitSensors.sensors() = { - createPmSensor("", "/run/devmap/sensors/CPU_CORE_TEMP")}; - config.pmUnitSensorsList() = {pmUnitSensors}; - EXPECT_FALSE(configValidator_.isValid(config, platformConfig_)); - pmUnitSensors.sensors() = { - createPmSensor("sensor1", "/run/devmap/eeproms/BCB_EEPROMS")}; - config.pmUnitSensorsList() = {pmUnitSensors}; - EXPECT_FALSE(configValidator_.isValid(config, platformConfig_)); - pmUnitSensors.sensors() = { - createPmSensor("sensor1", "/run/devmap/sensors/CPU_CORE_TEMP"), - createPmSensor("sensor1", "/run/devmap/sensors/CPU_CORE_TEMP2")}; - config.pmUnitSensorsList() = {pmUnitSensors}; - EXPECT_FALSE(configValidator_.isValid(config, platformConfig_)); +TEST_F(ConfigValidatorTest, PmValidPmSensors) { + const auto slotPath = "/BCB_SLOT@0"; + const auto pmSensors = { + createPmSensor("sensor1", "/run/devmap/sensors/BCB_FAN_CPLD/pwm3"), + createPmSensor("sensor2", "/run/devmap/sensors/BCB_FAN_CPLD2/fan_input")}; + // Invalid PmSensor -- Unmatching SlotPaths for BCB_FAN_CPLD2 + platformConfig_.symbolicLinkToDevicePath() = { + {"/run/devmap/sensors/BCB_FAN_CPLD", "/BCB_SLOT@0/[BCB_FAN_CPLD]"}, + {"/run/devmap/sensors/BCB_FAN_CPLD2", "/[BCB_FAN_CPLD2]"}}; + EXPECT_CALL(*mockPmConfigValidator_, isValidDeviceName(platformConfig_, _, _)) + .WillOnce(Return(true)); + EXPECT_FALSE(configValidator_.isPmValidPmSensors( + platformConfig_, slotPath, pmSensors)); + // Invalid PmSensor -- Invalid Device Topology + platformConfig_.symbolicLinkToDevicePath() = { + {"/run/devmap/sensors/BCB_FAN_CPLD", "/BCB_SLOT@0/[BCB_FAN_CPLD]"}, + {"/run/devmap/sensors/BCB_FAN_CPLD2", "/BCB_SLOT@0/[BCB_FAN_CPLD2]"}}; + EXPECT_CALL(*mockPmConfigValidator_, isValidDeviceName(platformConfig_, _, _)) + .WillOnce(Return(false)); + EXPECT_FALSE(configValidator_.isPmValidPmSensors( + platformConfig_, slotPath, pmSensors)); + // Valid PmSensor + EXPECT_CALL(*mockPmConfigValidator_, isValidDeviceName(platformConfig_, _, _)) + .Times(2) + .WillRepeatedly(Return(true)); + EXPECT_TRUE(configValidator_.isPmValidPmSensors( + platformConfig_, slotPath, pmSensors)); }