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