1 #include "common/test/mocked_utils.hpp" 2 #include "libpldmresponder/bios_enum_attribute.hpp" 3 #include "mocked_bios.hpp" 4 5 #include <nlohmann/json.hpp> 6 7 #include <memory> 8 9 #include <gmock/gmock.h> 10 #include <gtest/gtest.h> 11 12 using namespace pldm::responder::bios; 13 using namespace pldm::utils; 14 15 using ::testing::_; 16 using ::testing::ElementsAreArray; 17 using ::testing::Return; 18 using ::testing::StrEq; 19 using ::testing::Throw; 20 21 class TestBIOSEnumAttribute : public ::testing::Test 22 { 23 public: 24 const auto& getPossibleValues(const BIOSEnumAttribute& attribute) 25 { 26 return attribute.possibleValues; 27 } 28 29 const auto& getDefaultValue(const BIOSEnumAttribute& attribute) 30 { 31 return attribute.defaultValue; 32 } 33 }; 34 35 TEST_F(TestBIOSEnumAttribute, CtorTest) 36 { 37 auto jsonEnumReadOnly = R"({ 38 "attribute_name" : "CodeUpdatePolicy", 39 "possible_values" : [ "Concurrent", "Disruptive" ], 40 "default_values" : [ "Concurrent" ], 41 "readOnly" : true, 42 "helpText" : "HelpText", 43 "displayName" : "DisplayName" 44 })"_json; 45 46 BIOSEnumAttribute enumReadOnly{jsonEnumReadOnly, nullptr}; 47 EXPECT_EQ(enumReadOnly.name, "CodeUpdatePolicy"); 48 EXPECT_TRUE(enumReadOnly.readOnly); 49 EXPECT_THAT(getPossibleValues(enumReadOnly), 50 ElementsAreArray({"Concurrent", "Disruptive"})); 51 EXPECT_EQ(getDefaultValue(enumReadOnly), "Concurrent"); 52 53 auto jsonEnumReadOnlyError = R"({ 54 "attribute_name" : "CodeUpdatePolicy", 55 "possible_value" : [ "Concurrent", "Disruptive" ], 56 "default_values" : [ "Concurrent" ], 57 "readOnly" : true, 58 "helpText" : "HelpText", 59 "displayName" : "DisplayName" 60 })"_json; // possible_value -> possible_values 61 EXPECT_THROW((BIOSEnumAttribute{jsonEnumReadOnlyError, nullptr}), 62 Json::exception); 63 64 auto jsonEnumReadWrite = R"({ 65 "attribute_name" : "FWBootSide", 66 "possible_values" : [ "Perm", "Temp" ], 67 "default_values" : [ "Perm" ], 68 "readOnly" : false, 69 "helpText" : "HelpText", 70 "displayName" : "DisplayName", 71 "dbus": 72 { 73 "object_path" : "/xyz/abc/def", 74 "interface" : "xyz.openbmc.FWBoot.Side", 75 "property_name" : "Side", 76 "property_type" : "bool", 77 "property_values" : [true, false] 78 } 79 })"_json; 80 81 BIOSEnumAttribute enumReadWrite{jsonEnumReadWrite, nullptr}; 82 EXPECT_EQ(enumReadWrite.name, "FWBootSide"); 83 EXPECT_TRUE(!enumReadWrite.readOnly); 84 } 85 86 TEST_F(TestBIOSEnumAttribute, ConstructEntry) 87 { 88 MockBIOSStringTable biosStringTable; 89 MockdBusHandler dbusHandler; 90 91 auto jsonEnumReadOnly = R"({ 92 "attribute_name" : "CodeUpdatePolicy", 93 "possible_values" : [ "Concurrent", "Disruptive" ], 94 "default_values" : [ "Disruptive" ], 95 "readOnly" : true, 96 "helpText" : "HelpText", 97 "displayName" : "DisplayName" 98 })"_json; 99 100 std::vector<uint8_t> expectedAttrEntry{ 101 0, 0, /* attr handle */ 102 0x80, /* attr type enum read-only*/ 103 4, 0, /* attr name handle */ 104 2, /* number of possible value */ 105 2, 0, /* possible value handle */ 106 3, 0, /* possible value handle */ 107 1, /* number of default value */ 108 1 /* defaut value string handle index */ 109 }; 110 111 std::vector<uint8_t> expectedAttrValueEntry{ 112 0, 0, /* attr handle */ 113 0x80, /* attr type enum read-only*/ 114 1, /* number of current value */ 115 1 /* current value string handle index */ 116 }; 117 118 BIOSEnumAttribute enumReadOnly{jsonEnumReadOnly, nullptr}; 119 120 ON_CALL(biosStringTable, findHandle(StrEq("Concurrent"))) 121 .WillByDefault(Return(2)); 122 ON_CALL(biosStringTable, findHandle(StrEq("Disruptive"))) 123 .WillByDefault(Return(3)); 124 ON_CALL(biosStringTable, findHandle(StrEq("CodeUpdatePolicy"))) 125 .WillByDefault(Return(4)); 126 127 checkConstructEntry(enumReadOnly, biosStringTable, expectedAttrEntry, 128 expectedAttrValueEntry); 129 130 auto jsonEnumReadWrite = R"({ 131 "attribute_name" : "CodeUpdatePolicy", 132 "possible_values" : [ "Concurrent", "Disruptive" ], 133 "default_values" : [ "Disruptive" ], 134 "readOnly" : false, 135 "helpText" : "HelpText", 136 "displayName" : "DisplayName", 137 "dbus": 138 { 139 "object_path" : "/xyz/abc/def", 140 "interface" : "xyz.openbmc.abc.def", 141 "property_name" : "Policy", 142 "property_type" : "bool", 143 "property_values" : [true, false] 144 } 145 })"_json; 146 147 BIOSEnumAttribute enumReadWrite{jsonEnumReadWrite, &dbusHandler}; 148 149 EXPECT_CALL(dbusHandler, 150 getDbusPropertyVariant(StrEq("/xyz/abc/def"), StrEq("Policy"), 151 StrEq("xyz.openbmc.abc.def"))) 152 .WillOnce(Throw(std::exception())); 153 154 /* Set expected attr type to read-write */ 155 expectedAttrEntry[2] = PLDM_BIOS_ENUMERATION; 156 expectedAttrValueEntry[2] = PLDM_BIOS_ENUMERATION; 157 158 checkConstructEntry(enumReadWrite, biosStringTable, expectedAttrEntry, 159 expectedAttrValueEntry); 160 161 EXPECT_CALL(dbusHandler, 162 getDbusPropertyVariant(StrEq("/xyz/abc/def"), StrEq("Policy"), 163 StrEq("xyz.openbmc.abc.def"))) 164 .WillOnce(Return(PropertyValue(true))); 165 166 expectedAttrValueEntry = { 167 0, 0, /* attr handle */ 168 0, /* attr type enum read-write*/ 169 1, /* number of current value */ 170 0 /* current value string handle index */ 171 }; 172 173 checkConstructEntry(enumReadWrite, biosStringTable, expectedAttrEntry, 174 expectedAttrValueEntry); 175 } 176 177 TEST_F(TestBIOSEnumAttribute, setAttrValueOnDbus) 178 { 179 MockBIOSStringTable biosStringTable; 180 MockdBusHandler dbusHandler; 181 182 auto jsonEnumReadWrite = R"({ 183 "attribute_name" : "CodeUpdatePolicy", 184 "possible_values" : [ "Concurrent", "Disruptive" ], 185 "default_values" : [ "Disruptive" ], 186 "readOnly" : false, 187 "helpText" : "HelpText", 188 "displayName" : "DisplayName", 189 "dbus": 190 { 191 "object_path" : "/xyz/abc/def", 192 "interface" : "xyz.openbmc.abc.def", 193 "property_name" : "Policy", 194 "property_type" : "bool", 195 "property_values" : [true, false] 196 } 197 })"_json; 198 DBusMapping dbusMapping{"/xyz/abc/def", "xyz.openbmc.abc.def", "Policy", 199 "bool"}; 200 201 BIOSEnumAttribute enumReadWrite{jsonEnumReadWrite, &dbusHandler}; 202 203 std::vector<uint8_t> attrEntry{ 204 0, 0, /* attr handle */ 205 0, /* attr type enum read-only*/ 206 4, 0, /* attr name handle */ 207 2, /* number of possible value */ 208 2, 0, /* possible value handle */ 209 3, 0, /* possible value handle */ 210 1, /* number of default value */ 211 1 /* defaut value string handle index */ 212 }; 213 214 ON_CALL(biosStringTable, findString(2)) 215 .WillByDefault(Return(std::string("Concurrent"))); 216 ON_CALL(biosStringTable, findString(3)) 217 .WillByDefault(Return(std::string("Disruptive"))); 218 219 std::vector<uint8_t> attrValueEntry{ 220 0, 0, /* attr handle */ 221 0, /* attr type enum read-only*/ 222 1, /* number of current value */ 223 0 /* current value string handle index */ 224 }; 225 226 EXPECT_CALL(dbusHandler, 227 setDbusProperty(dbusMapping, PropertyValue{bool(true)})) 228 .Times(1); 229 enumReadWrite.setAttrValueOnDbus( 230 reinterpret_cast<pldm_bios_attr_val_table_entry*>( 231 attrValueEntry.data()), 232 reinterpret_cast<pldm_bios_attr_table_entry*>(attrEntry.data()), 233 biosStringTable); 234 } 235