blob: 2a2b72f51664074d28b01a0c31201c86e1b798eb [file] [log] [blame]
John Wangd9659342020-02-27 16:46:05 +08001#include "bios_utils.hpp"
2#include "libpldmresponder/bios_config.hpp"
3#include "libpldmresponder/bios_string_attribute.hpp"
4#include "mocked_bios.hpp"
5#include "mocked_utils.hpp"
6
7#include <fstream>
8#include <memory>
9#include <nlohmann/json.hpp>
10
11#include <gmock/gmock.h>
12#include <gtest/gtest.h>
13
14using namespace pldm::bios::utils;
15
16using ::testing::_;
17using ::testing::ElementsAreArray;
18using ::testing::Throw;
19
20class TestBIOSConfig : public ::testing::Test
21{
22 public:
23 static void SetUpTestCase() // will execute once at the begining of all
24 // TestBIOSConfig objects
25 {
26 char tmpdir[] = "/tmp/BIOSTables.XXXXXX";
27 tableDir = fs::path(mkdtemp(tmpdir));
28
29 std::vector<fs::path> paths = {
30 "./bios_jsons/string_attrs.json",
31 };
32
33 for (auto& path : paths)
34 {
35 std::ifstream file;
36 file.open(path);
37 auto j = Json::parse(file);
38 jsons.emplace_back(j);
39 }
40 }
41
42 std::optional<Json> findJsonEntry(const std::string& name)
43 {
44 for (auto& json : jsons)
45 {
46 auto entries = json.at("entries");
47 for (auto& entry : entries)
48 {
49 auto n = entry.at("attribute_name").get<std::string>();
50 if (n == name)
51 {
52 return entry;
53 }
54 }
55 }
56 return std::nullopt;
57 }
58
59 static void TearDownTestCase() // will be executed once at th end of all
60 // TestBIOSConfig objects
61 {
62 fs::remove_all(tableDir);
63 }
64
65 static fs::path tableDir;
66 static std::vector<Json> jsons;
67};
68
69fs::path TestBIOSConfig::tableDir;
70std::vector<Json> TestBIOSConfig::jsons;
71
72TEST_F(TestBIOSConfig, buildTablesTest)
73{
74 MockdBusHandler dbusHandler;
75
76 ON_CALL(dbusHandler, getDbusPropertyVariant(_, _, _))
77 .WillByDefault(Throw(std::exception()));
78
79 BIOSConfig biosConfig("./bios_jsons", tableDir.c_str(), &dbusHandler);
80 biosConfig.buildTables();
81
82 auto stringTable = biosConfig.getBIOSTable(PLDM_BIOS_STRING_TABLE);
83 auto attrTable = biosConfig.getBIOSTable(PLDM_BIOS_ATTR_TABLE);
84 auto attrValueTable = biosConfig.getBIOSTable(PLDM_BIOS_ATTR_VAL_TABLE);
85
86 EXPECT_TRUE(stringTable);
87 EXPECT_TRUE(attrTable);
88 EXPECT_TRUE(attrValueTable);
89
90 std::set<std::string> expectedStrings = {"HMCManagedState",
91 "On",
92 "Off",
93 "FWBootSide",
94 "Perm",
95 "Temp",
96 "InbandCodeUpdate",
97 "Allowed",
98 "NotAllowed",
99 "CodeUpdatePolicy",
100 "Concurrent",
101 "Disruptive",
102 "VDD_AVSBUS_RAIL",
103 "SBE_IMAGE_MINIMUM_VALID_ECS",
104 "INTEGER_INVALID_CASE",
105 "str_example1",
106 "str_example2",
107 "str_example3"};
108 std::set<std::string> strings;
109 for (auto entry : BIOSTableIter<PLDM_BIOS_STRING_TABLE>(
110 stringTable->data(), stringTable->size()))
111 {
112 auto str = table::string::decodeString(entry);
113 strings.emplace(str);
114 }
115
116 EXPECT_EQ(strings, expectedStrings);
117
118 BIOSStringTable biosStringTable(*stringTable);
119
120 for (auto entry : BIOSTableIter<PLDM_BIOS_ATTR_TABLE>(attrTable->data(),
121 attrTable->size()))
122 {
123 auto header = table::attribute::decodeHeader(entry);
124 auto attrName = biosStringTable.findString(header.stringHandle);
125 auto jsonEntry = findJsonEntry(attrName);
126 EXPECT_TRUE(jsonEntry);
127 switch (header.attrType)
128 {
129 case PLDM_BIOS_STRING:
130 case PLDM_BIOS_STRING_READ_ONLY:
131 {
132 auto stringField = table::attribute::decodeStringEntry(entry);
133 auto stringType = BIOSStringAttribute::strTypeMap.at(
134 jsonEntry->at("string_type").get<std::string>());
135 EXPECT_EQ(stringField.stringType,
136 static_cast<uint8_t>(stringType));
137
138 EXPECT_EQ(
139 stringField.minLength,
140 jsonEntry->at("minimum_string_length").get<uint16_t>());
141 EXPECT_EQ(
142 stringField.maxLength,
143 jsonEntry->at("maximum_string_length").get<uint16_t>());
144 EXPECT_EQ(
145 stringField.defLength,
146 jsonEntry->at("default_string_length").get<uint16_t>());
147 EXPECT_EQ(stringField.defString,
148 jsonEntry->at("default_string").get<std::string>());
149 break;
150 }
151 default:
152 EXPECT_TRUE(false);
153 break;
154 }
155 }
156
157 for (auto entry : BIOSTableIter<PLDM_BIOS_ATTR_VAL_TABLE>(
158 attrValueTable->data(), attrValueTable->size()))
159 {
160 auto header = table::attribute_value::decodeHeader(entry);
161 auto attrEntry =
162 table::attribute::findByHandle(*attrTable, header.attrHandle);
163 auto attrHeader = table::attribute::decodeHeader(attrEntry);
164 auto attrName = biosStringTable.findString(attrHeader.stringHandle);
165 auto jsonEntry = findJsonEntry(attrName);
166 EXPECT_TRUE(jsonEntry);
167 switch (header.attrType)
168 {
169 case PLDM_BIOS_STRING:
170 case PLDM_BIOS_STRING_READ_ONLY:
171 {
172 auto value = table::attribute_value::decodeStringEntry(entry);
173 auto defValue =
174 jsonEntry->at("default_string").get<std::string>();
175 EXPECT_EQ(value, defValue);
176 break;
177 }
178 default:
179 EXPECT_TRUE(false);
180 break;
181 }
182 }
183}
184
185TEST_F(TestBIOSConfig, setAttrValue)
186{
187 MockdBusHandler dbusHandler;
188
189 BIOSConfig biosConfig("./bios_jsons", tableDir.c_str(), &dbusHandler);
190 biosConfig.removeTables();
191 biosConfig.buildTables();
192
193 auto stringTable = biosConfig.getBIOSTable(PLDM_BIOS_STRING_TABLE);
194 auto attrTable = biosConfig.getBIOSTable(PLDM_BIOS_ATTR_TABLE);
195
196 BIOSStringTable biosStringTable(*stringTable);
197 BIOSTableIter<PLDM_BIOS_ATTR_TABLE> attrTableIter(attrTable->data(),
198 attrTable->size());
199 auto stringHandle = biosStringTable.findHandle("str_example1");
200 uint16_t attrHandle{};
201
202 for (auto entry : BIOSTableIter<PLDM_BIOS_ATTR_TABLE>(attrTable->data(),
203 attrTable->size()))
204 {
205 auto header = table::attribute::decodeHeader(entry);
206 if (header.stringHandle == stringHandle)
207 {
208 attrHandle = header.attrHandle;
209 break;
210 }
211 }
212
213 EXPECT_NE(attrHandle, 0);
214
215 std::vector<uint8_t> attrValueEntry{
216 0, 0, /* attr handle */
217 1, /* attr type string read-write */
218 4, 0, /* current string length */
219 'a', 'b', 'c', 'd', /* defaut value string handle index */
220 };
221
222 attrValueEntry[0] = attrHandle & 0xff;
223 attrValueEntry[1] = (attrHandle >> 8) & 0xff;
224
225 DBusMapping dbusMapping{"/xyz/abc/def",
226 "xyz.openbmc_project.str_example1.value",
227 "Str_example1", "string"};
228 PropertyValue value = std::string("abcd");
229 EXPECT_CALL(dbusHandler, setDbusProperty(dbusMapping, value)).Times(1);
230
231 auto rc =
232 biosConfig.setAttrValue(attrValueEntry.data(), attrValueEntry.size());
233 EXPECT_EQ(rc, PLDM_SUCCESS);
234
235 auto attrValueTable = biosConfig.getBIOSTable(PLDM_BIOS_ATTR_VAL_TABLE);
236 auto findEntry =
237 [&attrValueTable](
238 uint16_t handle) -> const pldm_bios_attr_val_table_entry* {
239 for (auto entry : BIOSTableIter<PLDM_BIOS_ATTR_VAL_TABLE>(
240 attrValueTable->data(), attrValueTable->size()))
241 {
242 auto [attrHandle, _] = table::attribute_value::decodeHeader(entry);
243 if (attrHandle == handle)
244 return entry;
245 }
246 return nullptr;
247 };
248
249 auto entry = findEntry(attrHandle);
250 EXPECT_NE(entry, nullptr);
251
252 auto p = reinterpret_cast<const uint8_t*>(entry);
253 EXPECT_THAT(std::vector<uint8_t>(p, p + attrValueEntry.size()),
254 ElementsAreArray(attrValueEntry));
255}