1 #include "rde/rde_dictionary_manager.hpp"
2
3 #include <cstring>
4 #include <memory>
5 #include <optional>
6 #include <span>
7
8 #include <gmock/gmock-matchers.h>
9 #include <gmock/gmock.h>
10 #include <gtest/gtest.h>
11
12 namespace bios_bmc_smm_error_logger
13 {
14 namespace rde
15 {
16
17 constexpr std::array<uint8_t, 132> dummyDictionary1{
18 {0x00, 0x03, 0x02, 0x00, 0x00, 0x00, 0x17, 0x01, 0x00, 0x00, 0x0, 0x0,
19 0xc, 0x0, 0x0, 0xf0, 0xf0, 0xf1, 0x17, 0x1, 0x0, 0x0, 0x0, 0x0,
20 0x0, 0x16, 0x0, 0x5, 0x0, 0xc, 0x84, 0x0, 0x14, 0x0, 0x0, 0x48,
21 0x0, 0x1, 0x0, 0x13, 0x90, 0x0, 0x56, 0x1, 0x0, 0x0, 0x0, 0x0,
22 0x0, 0x3, 0xa3, 0x0, 0x74, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x16,
23 0xa6, 0x0, 0x34, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x16, 0xbc, 0x0,
24 0x64, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x13, 0xd2, 0x0, 0x0, 0x0,
25 0x0, 0x52, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x74, 0x0, 0x0, 0x0,
26 0x0, 0x0, 0x0, 0xf, 0xe5, 0x0, 0x46, 0x1, 0x0, 0x66, 0x0, 0x3,
27 0x0, 0xb, 0xf4, 0x0, 0x50, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9,
28 0xff, 0x0, 0x50, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0x8, 0x1}};
29
30 constexpr std::array<uint8_t, 14> dummyDictionary2{
31 {0x65, 0x0, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x41, 0x72, 0x72, 0x61, 0x79,
32 0x50, 0x72}};
33
34 class RdeDictionaryManagerTest : public ::testing::Test
35 {
36 protected:
37 uint32_t resourceId = 1;
38 DictionaryManager dm;
39 };
40
TEST_F(RdeDictionaryManagerTest,DictionarySetTest)41 TEST_F(RdeDictionaryManagerTest, DictionarySetTest)
42 {
43 // Add a single dictionary.
44 dm.startDictionaryEntry(resourceId, std::span(dummyDictionary1));
45 EXPECT_THAT(dm.getDictionaryCount(), 0);
46
47 // Mark the dictionary as a valid dictionary.
48 dm.markDataComplete(resourceId);
49 EXPECT_THAT(dm.getDictionaryCount(), 1);
50
51 // Request the dictionary back and verify the data.
52 auto dataOrErr = dm.getDictionary(resourceId);
53 EXPECT_TRUE(dataOrErr);
54 EXPECT_THAT((*dataOrErr).size_bytes(), dummyDictionary1.size());
55 EXPECT_THAT(memcmp((*dataOrErr).data(), dummyDictionary1.data(),
56 dummyDictionary1.size()),
57 0);
58 }
59
TEST_F(RdeDictionaryManagerTest,DictionaryNotSetTest)60 TEST_F(RdeDictionaryManagerTest, DictionaryNotSetTest)
61 {
62 // Add a single dictionary.
63 dm.startDictionaryEntry(resourceId, std::span(dummyDictionary1));
64 EXPECT_THAT(dm.getDictionaryCount(), 0);
65 // Request the dictionary back without marking it complete. Request should
66 // fail.
67 EXPECT_FALSE(dm.getDictionary(resourceId));
68 }
69
TEST_F(RdeDictionaryManagerTest,DictionaryMultiSetTest)70 TEST_F(RdeDictionaryManagerTest, DictionaryMultiSetTest)
71 {
72 // Creates a dictionary
73 dm.startDictionaryEntry(resourceId, std::span(dummyDictionary1));
74 EXPECT_THAT(dm.getDictionaryCount(), 0);
75 dm.markDataComplete(resourceId);
76 EXPECT_THAT(dm.getDictionaryCount(), 1);
77
78 // Creates a second dictionary.
79 dm.startDictionaryEntry(annotationResourceId, std::span(dummyDictionary2));
80 dm.markDataComplete(annotationResourceId);
81 EXPECT_THAT(dm.getDictionaryCount(), 2);
82
83 auto data1OrErr = dm.getDictionary(resourceId);
84 EXPECT_TRUE(data1OrErr);
85 EXPECT_THAT((*data1OrErr).size_bytes(), dummyDictionary1.size());
86 EXPECT_THAT(memcmp((*data1OrErr).data(), dummyDictionary1.data(),
87 dummyDictionary1.size()),
88 0);
89
90 auto data2OrErr = dm.getDictionary(annotationResourceId);
91 EXPECT_TRUE(data2OrErr);
92 EXPECT_THAT((*data2OrErr).size_bytes(), dummyDictionary2.size());
93 EXPECT_THAT(memcmp((*data2OrErr).data(), dummyDictionary2.data(),
94 dummyDictionary2.size()),
95 0);
96 }
97
TEST_F(RdeDictionaryManagerTest,DictionaryOverwriteTest)98 TEST_F(RdeDictionaryManagerTest, DictionaryOverwriteTest)
99 {
100 dm.startDictionaryEntry(resourceId, std::span(dummyDictionary2));
101
102 // Recreate another one on the same location.
103 dm.startDictionaryEntry(resourceId, std::span(dummyDictionary1));
104 EXPECT_THAT(dm.getDictionaryCount(), 0);
105 dm.markDataComplete(resourceId);
106 EXPECT_THAT(dm.getDictionaryCount(), 1);
107
108 auto dataOrErr = dm.getDictionary(resourceId);
109 EXPECT_TRUE(dataOrErr);
110 EXPECT_THAT((*dataOrErr).size_bytes(), dummyDictionary1.size());
111 EXPECT_THAT(memcmp((*dataOrErr).data(), dummyDictionary1.data(),
112 dummyDictionary1.size()),
113 0);
114
115 // Recreate another one on the same location.
116 dm.startDictionaryEntry(resourceId, std::span(dummyDictionary2));
117 EXPECT_THAT(dm.getDictionaryCount(), 0);
118 dm.markDataComplete(resourceId);
119 EXPECT_THAT(dm.getDictionaryCount(), 1);
120
121 auto newDataOrErr = dm.getDictionary(resourceId);
122 EXPECT_TRUE(newDataOrErr);
123 EXPECT_THAT((*newDataOrErr).size_bytes(), dummyDictionary2.size());
124 EXPECT_THAT(memcmp((*newDataOrErr).data(), dummyDictionary2.data(),
125 dummyDictionary2.size()),
126 0);
127 }
128
TEST_F(RdeDictionaryManagerTest,DictionaryAppendDataTest)129 TEST_F(RdeDictionaryManagerTest, DictionaryAppendDataTest)
130 {
131 // Creates a dictionary
132 dm.startDictionaryEntry(resourceId, std::span(dummyDictionary1));
133 EXPECT_THAT(dm.getDictionaryCount(), 0);
134
135 // Lets copy the dictionary in two sizes.
136 const uint32_t copySize1 = dummyDictionary2.size() / 2;
137 const uint32_t copySize2 = dummyDictionary2.size() - copySize1;
138
139 // Overwrite on the same location as before.
140 dm.startDictionaryEntry(resourceId,
141 std::span(dummyDictionary2.data(), copySize1));
142 dm.addDictionaryData(
143 resourceId, std::span(dummyDictionary2.data() + copySize1, copySize2));
144 dm.markDataComplete(resourceId);
145 EXPECT_THAT(dm.getDictionaryCount(), 1);
146
147 auto dataOrErr = dm.getDictionary(resourceId);
148 EXPECT_TRUE(dataOrErr);
149 EXPECT_THAT((*dataOrErr).size_bytes(), dummyDictionary2.size());
150 EXPECT_THAT(memcmp((*dataOrErr).data(), dummyDictionary2.data(),
151 dummyDictionary2.size()),
152 0);
153 }
154
TEST_F(RdeDictionaryManagerTest,DictionaryOverrideWithAddDataTest)155 TEST_F(RdeDictionaryManagerTest, DictionaryOverrideWithAddDataTest)
156 {
157 dm.startDictionaryEntry(resourceId, std::span(dummyDictionary1));
158 dm.markDataComplete(resourceId);
159 EXPECT_THAT(dm.getDictionaryCount(), 1);
160
161 dm.addDictionaryData(resourceId, std::span(dummyDictionary2));
162 EXPECT_THAT(dm.getDictionaryCount(), 0);
163 dm.markDataComplete(resourceId);
164 EXPECT_THAT(dm.getDictionaryCount(), 1);
165 }
166
TEST_F(RdeDictionaryManagerTest,DictionaryInvalidateTest)167 TEST_F(RdeDictionaryManagerTest, DictionaryInvalidateTest)
168 {
169 dm.startDictionaryEntry(resourceId, std::span(dummyDictionary1));
170 dm.markDataComplete(resourceId);
171 EXPECT_THAT(dm.getDictionaryCount(), 1);
172
173 dm.invalidateDictionaries();
174 EXPECT_THAT(dm.getDictionaryCount(), 0);
175 }
176
177 } // namespace rde
178 } // namespace bios_bmc_smm_error_logger
179