| // Copyright 2023 The ChromiumOS Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "rmad/ssfc/ssfc_prober.h" |
| |
| #include <memory> |
| #include <utility> |
| #include <vector> |
| |
| #include <gmock/gmock.h> |
| #include <gtest/gtest.h> |
| |
| #include "rmad/system/mock_runtime_probe_client.h" |
| #include "rmad/utils/mock_cbi_utils.h" |
| #include "rmad/utils/mock_cros_config_utils.h" |
| |
| using testing::_; |
| using testing::DoAll; |
| using testing::NiceMock; |
| using testing::Return; |
| using testing::SetArgPointee; |
| |
| namespace { |
| |
| constexpr uint32_t kOriginalSsfcValue = 0x11; |
| constexpr uint32_t kSsfcMask = 0x10; |
| |
| constexpr rmad::RmadComponent kComponentApI2c = rmad::RMAD_COMPONENT_AP_I2C; |
| constexpr uint32_t kApI2cDefaultValue = 0; |
| constexpr char kApI2cName1[] = "ap_i2c_1"; |
| constexpr uint32_t kApI2cValue1 = 0x1; |
| constexpr char kApI2cName2[] = "ap_i2c_2"; |
| constexpr uint32_t kApI2cValue2 = 0x2; |
| |
| constexpr rmad::RmadComponent kComponentEcI2c = rmad::RMAD_COMPONENT_EC_I2C; |
| constexpr uint32_t kEcI2cDefaultValue = 0x4; |
| constexpr char kEcI2cName1[] = "ec_i2c_1"; |
| constexpr uint32_t kEcI2cValue1 = 0x8; |
| constexpr char kEcI2cName2[] = "ec_i2c_2"; |
| constexpr uint32_t kEcI2cValue2 = 0xc; |
| |
| } // namespace |
| |
| namespace rmad { |
| |
| class SsfcProberImplTest : public testing::Test { |
| public: |
| SsfcProberImplTest() = default; |
| |
| std::unique_ptr<SsfcProberImpl> CreateSsfcProber( |
| const RmadConfig& rmad_config = {}, |
| bool probe_success = true, |
| const std::vector<std::pair<RmadComponent, std::string>>& |
| probed_components = {{kComponentApI2c, kApI2cName1}, |
| {kComponentEcI2c, kEcI2cName1}}) { |
| // Mock |RuntimeProbeClient|. |
| auto mock_runtime_probe_client = |
| std::make_unique<NiceMock<MockRuntimeProbeClient>>(); |
| if (probe_success) { |
| ON_CALL(*mock_runtime_probe_client, ProbeSsfcComponents(_, _)) |
| .WillByDefault( |
| DoAll(SetArgPointee<1>(probed_components), Return(true))); |
| } else { |
| ON_CALL(*mock_runtime_probe_client, ProbeSsfcComponents(_, _)) |
| .WillByDefault(Return(false)); |
| } |
| |
| // Mock |CbiUtils|. |
| auto mock_cbi_utils = std::make_unique<NiceMock<MockCbiUtils>>(); |
| ON_CALL(*mock_cbi_utils, GetSsfc(_)) |
| .WillByDefault( |
| DoAll(SetArgPointee<0>(kOriginalSsfcValue), Return(true))); |
| |
| // Mock |CrosConfigUtils|. |
| auto mock_cros_config_utils = |
| std::make_unique<NiceMock<MockCrosConfigUtils>>(); |
| ON_CALL(*mock_cros_config_utils, GetRmadConfig(_)) |
| .WillByDefault(DoAll(SetArgPointee<0>(rmad_config), Return(true))); |
| |
| return std::make_unique<SsfcProberImpl>( |
| std::move(mock_runtime_probe_client), std::move(mock_cbi_utils), |
| std::move(mock_cros_config_utils)); |
| } |
| }; |
| |
| TEST_F(SsfcProberImplTest, IsSsfcRequired_True) { |
| RmadConfig rmad_config = {.ssfc = {.component_type_configs = {{}}}}; |
| auto ssfc_prober = CreateSsfcProber(rmad_config); |
| |
| EXPECT_TRUE(ssfc_prober->IsSsfcRequired()); |
| } |
| |
| TEST_F(SsfcProberImplTest, IsSsfcRequired_False) { |
| auto ssfc_prober = CreateSsfcProber(); |
| |
| EXPECT_FALSE(ssfc_prober->IsSsfcRequired()); |
| } |
| |
| TEST_F(SsfcProberImplTest, ProbeSsfc_NotRequired) { |
| auto ssfc_prober = CreateSsfcProber(); |
| |
| uint32_t ssfc; |
| EXPECT_FALSE(ssfc_prober->ProbeSsfc(&ssfc)); |
| } |
| |
| TEST_F(SsfcProberImplTest, ProbeSsfc_ProbeFailed) { |
| RmadConfig rmad_config = { |
| .ssfc = {.mask = kSsfcMask, |
| .component_type_configs = { |
| { |
| .default_value = kApI2cDefaultValue, |
| .probeable_components = {{kApI2cName1, kApI2cValue1}, |
| {kApI2cName2, kApI2cValue2}}, |
| }, |
| { |
| .default_value = kEcI2cDefaultValue, |
| .probeable_components = {{kEcI2cName1, kEcI2cValue1}, |
| {kEcI2cName2, kEcI2cValue2}}, |
| }, |
| }}}; |
| auto ssfc_prober = CreateSsfcProber(rmad_config, false); |
| |
| uint32_t ssfc; |
| EXPECT_FALSE(ssfc_prober->ProbeSsfc(&ssfc)); |
| } |
| |
| TEST_F(SsfcProberImplTest, ProbeSsfc_Success_NoMask) { |
| RmadConfig rmad_config = { |
| .ssfc = {.component_type_configs = { |
| { |
| .default_value = kApI2cDefaultValue, |
| .probeable_components = {{kApI2cName1, kApI2cValue1}, |
| {kApI2cName2, kApI2cValue2}}, |
| }, |
| { |
| .default_value = kEcI2cDefaultValue, |
| .probeable_components = {{kEcI2cName1, kEcI2cValue1}, |
| {kEcI2cName2, kEcI2cValue2}}, |
| }, |
| }}}; |
| auto ssfc_prober = CreateSsfcProber(rmad_config); |
| |
| uint32_t ssfc; |
| EXPECT_TRUE(ssfc_prober->ProbeSsfc(&ssfc)); |
| EXPECT_EQ(kApI2cValue1 | kEcI2cValue1, ssfc); |
| } |
| |
| TEST_F(SsfcProberImplTest, ProbeSsfc_Success_Mask) { |
| RmadConfig rmad_config = { |
| .ssfc = {.mask = kSsfcMask, |
| .component_type_configs = { |
| { |
| .default_value = kApI2cDefaultValue, |
| .probeable_components = {{kApI2cName1, kApI2cValue1}, |
| {kApI2cName2, kApI2cValue2}}, |
| }, |
| { |
| .default_value = kEcI2cDefaultValue, |
| .probeable_components = {{kEcI2cName1, kEcI2cValue1}, |
| {kEcI2cName2, kEcI2cValue2}}, |
| }, |
| }}}; |
| auto ssfc_prober = CreateSsfcProber(rmad_config); |
| |
| uint32_t ssfc; |
| EXPECT_TRUE(ssfc_prober->ProbeSsfc(&ssfc)); |
| EXPECT_EQ((kOriginalSsfcValue & kSsfcMask) | kApI2cValue1 | kEcI2cValue1, |
| ssfc); |
| } |
| |
| TEST_F(SsfcProberImplTest, ProbeSsfc_Success_ComponentNotInConfig) { |
| RmadConfig rmad_config = { |
| .ssfc = {.component_type_configs = {{ |
| .default_value = kApI2cDefaultValue, |
| .probeable_components = {{kApI2cName1, kApI2cValue1}}, |
| }}}}; |
| std::vector<std::pair<RmadComponent, std::string>> probed_components = { |
| {kComponentApI2c, kApI2cName1}, {kComponentApI2c, kApI2cName2}}; |
| auto ssfc_prober = CreateSsfcProber(rmad_config, true, probed_components); |
| |
| uint32_t ssfc; |
| EXPECT_TRUE(ssfc_prober->ProbeSsfc(&ssfc)); |
| EXPECT_EQ(kApI2cValue1, ssfc); |
| } |
| |
| TEST_F(SsfcProberImplTest, ProbeSsfc_Success_DuplicateComponents) { |
| RmadConfig rmad_config = { |
| .ssfc = {.component_type_configs = {{ |
| .default_value = kApI2cDefaultValue, |
| .probeable_components = {{kApI2cName1, kApI2cValue1}}, |
| }}}}; |
| std::vector<std::pair<RmadComponent, std::string>> probed_components = { |
| {kComponentApI2c, kApI2cName1}, {kComponentApI2c, kApI2cName1}}; |
| auto ssfc_prober = CreateSsfcProber(rmad_config, true, probed_components); |
| |
| uint32_t ssfc; |
| EXPECT_TRUE(ssfc_prober->ProbeSsfc(&ssfc)); |
| EXPECT_EQ(kApI2cValue1, ssfc); |
| } |
| |
| TEST_F(SsfcProberImplTest, ProbeSsfc_Fail_MultipleComponents) { |
| RmadConfig rmad_config = { |
| .ssfc = {.component_type_configs = {{ |
| .default_value = kApI2cDefaultValue, |
| .probeable_components = {{kApI2cName1, kApI2cValue1}, |
| {kApI2cName2, kApI2cValue2}}, |
| }}}}; |
| std::vector<std::pair<RmadComponent, std::string>> probed_components = { |
| {kComponentApI2c, kApI2cName1}, {kComponentApI2c, kApI2cName2}}; |
| auto ssfc_prober = CreateSsfcProber(rmad_config, true, probed_components); |
| |
| uint32_t ssfc; |
| EXPECT_FALSE(ssfc_prober->ProbeSsfc(&ssfc)); |
| } |
| |
| } // namespace rmad |